Refactor into monorepo for v6 (#1837)

> You can [learn more about this here](https://blog.invertase.io/react-native-firebase-2019-7e334ca9bcc6).
This commit is contained in:
Michael Diarmid
2019-02-01 10:37:48 +00:00
committed by GitHub
parent 81e20ca6f3
commit 17d778cf66
489 changed files with 20500 additions and 59528 deletions

View File

@@ -0,0 +1,69 @@
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
}
}
plugins {
id "io.invertase.gradle.build" version "1.3"
}
project.ext {
set('react-native', [
versions: [
android : [
minSdk : 16,
targetSdk : 28,
compileSdk: 28,
// optional as gradle.buildTools comes with one by default
// overriding here though to match the version RN uses
buildTools: "28.0.3"
],
googlePlayServices: [
base: "16.0.1",
],
firebase : [
core: "16.0.6"
],
],
])
}
android {
defaultConfig {
multiDexEnabled true
}
lintOptions {
disable 'GradleCompatible'
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
repositories {
google()
jcenter()
}
dependencies {
implementation "com.google.firebase:firebase-core:${ReactNative.ext.getVersion("firebase", "core")}"
implementation "com.google.android.gms:play-services-base:${ReactNative.ext.getVersion("googlePlayServices", "base")}"
}
if (ReactNative.util.isExpo(project)) {
apply from: file("./expo.gradle")
}
ReactNative.shared.applyPackageVersion()
ReactNative.shared.applyDefaultExcludes()
ReactNative.module.applyAndroidVersions()
ReactNative.module.applyReactNativeDependency("api")

View File

@@ -0,0 +1,21 @@
logger.log(LogLevel.WARN, "")
logger.log(LogLevel.WARN, " -----------------------------------------------------------")
logger.log(LogLevel.WARN, " | WARNING REACT NATIVE FIREBASE WARNING |")
logger.log(LogLevel.WARN, " ----------------------------------------------------------- ")
logger.log(LogLevel.WARN, " | |")
logger.log(LogLevel.WARN, " | It looks like you're using Expo; |")
logger.log(LogLevel.WARN, " | we no longer test for or support Expo - therefore we |")
logger.log(LogLevel.WARN, " | will not offer support or gurantee stability whilst |")
logger.log(LogLevel.WARN, " | using this library on their platform. |")
logger.log(LogLevel.WARN, " | |")
logger.log(LogLevel.WARN, " | We recommend ejecting from Expo entirely should you |")
logger.log(LogLevel.WARN, " | wish to continue using React Native Firebase or if |")
logger.log(LogLevel.WARN, " | want to get official support for it from us. |")
logger.log(LogLevel.WARN, " | |")
logger.log(LogLevel.WARN, " | NOTE: Expo's 'ExpoFirebase' is an outdated, unofficial, |")
logger.log(LogLevel.WARN, " | direct copy of our source code, should you wish to use |")
logger.log(LogLevel.WARN, " | Expo + 'ExpoFirebase' instead then you do so at your |")
logger.log(LogLevel.WARN, " | own risk without support from React Native Firebase. |")
logger.log(LogLevel.WARN, " | |")
logger.log(LogLevel.WARN, " ----------------------------------------------------------- ")
logger.log(LogLevel.WARN, "")

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Tue Oct 09 01:55:27 BST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip

160
packages/app/android/gradlew vendored Normal file
View File

@@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

90
packages/app/android/gradlew.bat vendored Normal file
View File

@@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<!-- Disable the given check in this project -->
<issue id="GradleCompatible" severity="ignore" />
</lint>

View File

@@ -0,0 +1 @@
rootProject.name = '@react-native-firebase/app'

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.invertase.firebase">
<application>
<provider
android:name="io.invertase.firebase.common.ReactNativeFirebaseInitProvider"
android:authorities="${applicationId}.reactnativefirebaseinitprovider"
android:exported="false"
android:initOrder="101" /> <!-- Firebase = 100, using 101 to run after Firebase initialises -->
</application>
</manifest>

View File

@@ -0,0 +1,40 @@
package io.invertase.firebase.app;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import android.content.Context;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
public class ReactNativeFirebaseApp {
private static Context applicationContext;
public static Context getApplicationContext() {
return applicationContext;
}
public static void setApplicationContext(Context applicationContext) {
ReactNativeFirebaseApp.applicationContext = applicationContext;
}
public static void initializeSecondaryApp(String name) {
FirebaseOptions options = FirebaseOptions.fromResource(applicationContext);
FirebaseApp.initializeApp(applicationContext, options, name);
}
}

View File

@@ -0,0 +1,138 @@
package io.invertase.firebase.app;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.google.firebase.FirebaseApp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.invertase.firebase.common.RCTConvertFirebase;
import io.invertase.firebase.common.ReactNativeFirebaseEvent;
import io.invertase.firebase.common.ReactNativeFirebaseEventEmitter;
import io.invertase.firebase.common.ReactNativeFirebaseModule;
import io.invertase.firebase.common.ReactNativeFirebasePreferences;
public class ReactNativeFirebaseAppModule extends ReactNativeFirebaseModule {
private static final String TAG = "App";
ReactNativeFirebaseAppModule(ReactApplicationContext reactContext) {
super(reactContext, TAG);
}
@Override
public void initialize() {
super.initialize();
ReactNativeFirebaseEventEmitter.getSharedInstance().attachReactContext(getContext());
}
@ReactMethod
public void initializeApp(ReadableMap options, ReadableMap appConfig, Promise promise) {
FirebaseApp firebaseApp = RCTConvertFirebase.readableMapToFirebaseApp(
options, appConfig,
getContext()
);
WritableMap firebaseAppMap = RCTConvertFirebase.firebaseAppToWritableMap(firebaseApp);
promise.resolve(firebaseAppMap);
}
@ReactMethod
public void setAutomaticDataCollectionEnabled(String appName, Boolean enabled) {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
firebaseApp.setAutomaticResourceManagementEnabled(enabled);
}
@ReactMethod
public void deleteApp(String appName, Promise promise) {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
if (firebaseApp != null) {
firebaseApp.delete();
}
promise.resolve(null);
}
@ReactMethod
public void eventsNotifyReady(Boolean ready) {
ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance();
emitter.notifyJsReady(ready);
}
@ReactMethod
public void eventsGetListeners(Promise promise) {
ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance();
promise.resolve(emitter.getListenersMap());
}
@ReactMethod
public void eventsPing(String eventName, ReadableMap eventBody, Promise promise) {
ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance();
emitter.sendEvent(new ReactNativeFirebaseEvent(
eventName,
RCTConvertFirebase.readableMapToWritableMap(eventBody)
));
promise.resolve(RCTConvertFirebase.readableMapToWritableMap(eventBody));
}
@ReactMethod
public void eventsAddListener(String eventName) {
ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance();
emitter.addListener(eventName);
}
@ReactMethod
public void eventsRemoveListener(String eventName, Boolean all) {
ReactNativeFirebaseEventEmitter emitter = ReactNativeFirebaseEventEmitter.getSharedInstance();
emitter.removeListener(eventName, all);
}
@ReactMethod
public void getSavedPreferences(Promise promise) {
promise.resolve(ReactNativeFirebasePreferences.getSharedInstance().getAllAsWritableMap());
}
@ReactMethod
public void clearSavedPreferences(Promise promise) {
ReactNativeFirebasePreferences.getSharedInstance().clearAll();
promise.resolve(null);
}
@Override
public Map<String, Object> getConstants() {
Map<String, Object> constants = new HashMap<>();
List<Map<String, Object>> appsList = new ArrayList<>();
List<FirebaseApp> firebaseApps = FirebaseApp.getApps(getReactApplicationContext());
for (FirebaseApp app : firebaseApps) {
appsList.add(RCTConvertFirebase.firebaseAppToMap(app));
}
constants.put("apps", appsList);
return constants;
}
}

View File

@@ -0,0 +1,43 @@
package io.invertase.firebase.app;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@SuppressWarnings("unused")
public class ReactNativeFirebaseAppPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ReactNativeFirebaseAppModule(reactContext));
modules.add(new ReactNativeFirebaseUtilsModule(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

View File

@@ -0,0 +1,137 @@
package io.invertase.firebase.app;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import android.app.Activity;
import android.content.IntentSender;
import android.util.Log;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import java.util.HashMap;
import java.util.Map;
import io.invertase.firebase.common.ReactNativeFirebaseModule;
import io.invertase.firebase.common.SharedUtils;
public class ReactNativeFirebaseUtilsModule extends ReactNativeFirebaseModule {
private static final String TAG = "Utils";
ReactNativeFirebaseUtilsModule(ReactApplicationContext reactContext) {
super(reactContext, TAG);
}
@ReactMethod
public void androidGetPlayServicesStatus(Promise promise) {
promise.resolve(getPlayServicesStatusMap());
}
/**
* Prompt the device user to update play services
*/
@ReactMethod
public void androidPromptForPlayServices() {
int status = isGooglePlayServicesAvailable();
if (
status != ConnectionResult.SUCCESS &&
GoogleApiAvailability.getInstance().isUserResolvableError(status)
) {
Activity activity = getActivity();
if (activity != null) {
GoogleApiAvailability.getInstance()
.getErrorDialog(activity, status, status)
.show();
}
}
}
/**
* Prompt the device user to update play services
*/
@ReactMethod
public void androidResolutionForPlayServices() {
int status = isGooglePlayServicesAvailable();
ConnectionResult connectionResult = new ConnectionResult(status);
if (!connectionResult.isSuccess() && connectionResult.hasResolution()) {
Activity activity = getActivity();
if (activity != null) {
try {
connectionResult.startResolutionForResult(activity, status);
} catch (IntentSender.SendIntentException error) {
Log.d(TAG, "resolutionForPlayServices", error);
}
}
}
}
/**
* Prompt the device user to update Play Services
*/
@ReactMethod
public void androidMakePlayServicesAvailable() {
int status = isGooglePlayServicesAvailable();
if (status != ConnectionResult.SUCCESS) {
Activity activity = getActivity();
if (activity != null) {
GoogleApiAvailability.getInstance().makeGooglePlayServicesAvailable(activity);
}
}
}
private int isGooglePlayServicesAvailable() {
GoogleApiAvailability gapi = GoogleApiAvailability.getInstance();
return gapi.isGooglePlayServicesAvailable(getContext());
}
private WritableMap getPlayServicesStatusMap() {
WritableMap result = Arguments.createMap();
GoogleApiAvailability gapi = GoogleApiAvailability.getInstance();
int status = gapi.isGooglePlayServicesAvailable(getContext());
result.putInt("status", status);
if (status == ConnectionResult.SUCCESS) {
result.putBoolean("isAvailable", true);
} else {
result.putBoolean("isAvailable", false);
result.putString("error", gapi.getErrorString(status));
result.putBoolean("isUserResolvableError", gapi.isUserResolvableError(status));
result.putBoolean("hasResolution", new ConnectionResult(status).hasResolution());
}
return result;
}
@Override
public Map<String, Object> getConstants() {
Map<String, Object> constants = new HashMap<>();
constants.put("androidPlayServices", getPlayServicesStatusMap());
constants.put("isFirebaseTestLab", SharedUtils.isFirebaseTestLab());
return constants;
}
}

View File

@@ -0,0 +1,193 @@
package io.invertase.firebase.common;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import android.content.Context;
import android.util.Log;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
/**
* Utilities to convert to and from React Native bridge formats.
*/
public class RCTConvertFirebase {
private static String TAG = "RCTConvertFirebase";
public static Map<String, Object> firebaseAppToMap(FirebaseApp firebaseApp) {
String name = firebaseApp.getName();
FirebaseOptions appOptions = firebaseApp.getOptions();
Map<String, Object> root = new HashMap<>();
Map<String, Object> appConfig = new HashMap<>();
Map<String, Object> options = new HashMap<>();
appConfig.put("name", name);
appConfig.put("automaticDataCollectionEnabled", firebaseApp.isDataCollectionDefaultEnabled());
// TODO: Salakar: Firebase SDK does not support reading this value
// appConfig.put("automaticResourceManagement", false);
options.put("apiKey", appOptions.getApiKey());
options.put("appId", appOptions.getApplicationId());
options.put("projectId", appOptions.getProjectId());
options.put("databaseURL", appOptions.getDatabaseUrl());
options.put("gaTrackingId", appOptions.getGaTrackingId());
options.put("messagingSenderId", appOptions.getGcmSenderId());
options.put("storageBucket", appOptions.getStorageBucket());
root.put("options", options);
root.put("appConfig", appConfig);
return root;
}
public static WritableMap firebaseAppToWritableMap(FirebaseApp firebaseApp) {
return Arguments.makeNativeMap(firebaseAppToMap(firebaseApp));
}
public static FirebaseApp readableMapToFirebaseApp(
ReadableMap options,
ReadableMap appConfig,
Context context
) {
FirebaseOptions.Builder builder = new FirebaseOptions.Builder();
String name = appConfig.getString("name");
builder.setApiKey(options.getString("apiKey"));
builder.setApplicationId(options.getString("appId"));
builder.setProjectId(options.getString("projectId"));
builder.setDatabaseUrl(options.getString("databaseURL"));
if (options.hasKey("gaTrackingId")) {
builder.setGaTrackingId(options.getString("gaTrackingId"));
}
builder.setStorageBucket(options.getString("storageBucket"));
builder.setGcmSenderId(options.getString("messagingSenderId"));
FirebaseApp firebaseApp;
if (name.equals("[DEFAULT]")) {
firebaseApp = FirebaseApp.initializeApp(context, builder.build());
} else {
firebaseApp = FirebaseApp.initializeApp(context, builder.build(), name);
}
if (appConfig.hasKey("automaticDataCollectionEnabled")) {
firebaseApp.setDataCollectionDefaultEnabled(
appConfig.getBoolean("automaticDataCollectionEnabled")
);
}
if (appConfig.hasKey("automaticResourceManagement")) {
// https://developers.google.com/android/reference/com/google/firebase/FirebaseApp.html#setAutomaticResourceManagementEnabled(boolean)
firebaseApp.setAutomaticResourceManagementEnabled(
appConfig.getBoolean("automaticResourceManagement")
);
}
return firebaseApp;
}
/**
* Takes a value and calls the appropriate setter for its type on the target map + key
*
* @param key String key to set on target map
* @param value Object value to set on target map
* @param map WritableMap target map to write the value to
*/
@SuppressWarnings("unchecked")
public static void mapPutValue(String key, @Nullable Object value, WritableMap map) {
if (value == null) {
map.putNull(key);
return;
}
String type = value.getClass().getName();
switch (type) {
case "java.lang.Boolean":
map.putBoolean(key, (Boolean) value);
break;
case "java.lang.Long":
Long longVal = (Long) value;
map.putDouble(key, (double) longVal);
break;
case "java.lang.Float":
float floatVal = (float) value;
map.putDouble(key, (double) floatVal);
break;
case "java.lang.Double":
map.putDouble(key, (Double) value);
break;
case "java.lang.Integer":
map.putInt(key, (int) value);
break;
case "java.lang.String":
map.putString(key, (String) value);
break;
case "org.json.JSONObject$1":
map.putString(key, value.toString());
break;
default:
if (List.class.isAssignableFrom(value.getClass())) {
map.putArray(key, Arguments.makeNativeArray((List<Object>) value));
} else if (Map.class.isAssignableFrom(value.getClass())) {
WritableMap childMap = Arguments.createMap();
Map<String, Object> valueMap = (Map<String, Object>) value;
for (Map.Entry<String, Object> entry : valueMap.entrySet()) {
mapPutValue(entry.getKey(), entry.getValue(), childMap);
}
map.putMap(key, childMap);
} else {
Log.d(TAG, "utils:mapPutValue:unknownType:" + type);
map.putNull(key);
}
}
}
public static WritableMap readableMapToWritableMap(ReadableMap map) {
WritableMap writableMap = Arguments.createMap();
// https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/WritableNativeMap.java#L54
writableMap.merge(map);
return writableMap;
}
public static Map<String, Object> recursivelyDeconstructReadableMap(ReadableMap readableMap) {
// https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.java#L216
return readableMap.toHashMap();
}
public static List<Object> recursivelyDeconstructReadableArray(ReadableArray readableArray) {
// https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeArray.java#L175
return readableArray.toArrayList();
}
}

View File

@@ -0,0 +1,54 @@
package io.invertase.firebase.common;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import com.facebook.react.bridge.WritableMap;
import io.invertase.firebase.interfaces.NativeEvent;
public class ReactNativeFirebaseEvent implements NativeEvent {
private String eventName;
private WritableMap eventBody;
private String firebaseAppName;
public ReactNativeFirebaseEvent(String eventName, WritableMap eventBody) {
this.eventName = eventName;
this.eventBody = eventBody;
}
public ReactNativeFirebaseEvent(String eventName, WritableMap eventBody, String firebaseAppName) {
this.eventName = eventName;
this.eventBody = eventBody;
this.firebaseAppName = firebaseAppName;
}
@Override
public String getEventName() {
return eventName;
}
@Override
public WritableMap getEventBody() {
return eventBody;
}
@Override
public String getFirebaseAppName() {
return firebaseAppName;
}
}

View File

@@ -0,0 +1,162 @@
package io.invertase.firebase.common;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.MainThread;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import io.invertase.firebase.interfaces.NativeEvent;
public class ReactNativeFirebaseEventEmitter {
private static ReactNativeFirebaseEventEmitter sharedInstance = new ReactNativeFirebaseEventEmitter();
private final List<NativeEvent> queuedEvents = new ArrayList<>();
private final Handler handler = new Handler(Looper.getMainLooper());
private final HashMap<String, Integer> jsListeners = new HashMap<>();
private ReactContext reactContext;
private Boolean jsReady = false;
private int jsListenerCount;
public static ReactNativeFirebaseEventEmitter getSharedInstance() {
return sharedInstance;
}
public void attachReactContext(final ReactContext reactContext) {
handler.post(new Runnable() {
@Override
public void run() {
ReactNativeFirebaseEventEmitter.this.reactContext = reactContext;
sendQueuedEvents();
}
});
}
public void notifyJsReady(Boolean ready) {
handler.post(new Runnable() {
@Override
public void run() {
jsReady = ready;
sendQueuedEvents();
}
});
}
public void sendEvent(final NativeEvent event) {
handler.post(new Runnable() {
@Override
public void run() {
synchronized (jsListeners) {
if (!jsListeners.containsKey(event.getEventName()) || !emit(event)) {
queuedEvents.add(event);
}
}
}
});
}
public void addListener(String eventName) {
synchronized (jsListeners) {
jsListenerCount++;
if (!jsListeners.containsKey(eventName)) {
jsListeners.put(eventName, 1);
} else {
int listenersForEvent = jsListeners.get(eventName);
jsListeners.put(eventName, listenersForEvent + 1);
}
}
handler.post(new Runnable() {
@Override
public void run() {
sendQueuedEvents();
}
});
}
public void removeListener(String eventName, Boolean all) {
synchronized (jsListeners) {
if (jsListeners.containsKey(eventName)) {
int listenersForEvent = jsListeners.get(eventName);
if (listenersForEvent <= 1 || all) {
jsListeners.remove(eventName);
} else {
jsListeners.put(eventName, listenersForEvent - 1);
}
jsListenerCount -= all ? listenersForEvent : 1;
}
}
}
public WritableMap getListenersMap() {
WritableMap writableMap = Arguments.createMap();
WritableMap events = Arguments.createMap();
writableMap.putInt("listeners", jsListenerCount);
writableMap.putInt("queued", queuedEvents.size());
synchronized (jsListeners) {
for (HashMap.Entry<String, Integer> entry : jsListeners.entrySet()) {
events.putInt(entry.getKey(), entry.getValue());
}
}
writableMap.putMap("events", events);
return writableMap;
}
@MainThread
private void sendQueuedEvents() {
synchronized (jsListeners) {
for (NativeEvent event : new ArrayList<>(queuedEvents)) {
if (jsListeners.containsKey(event.getEventName())) {
queuedEvents.remove(event);
sendEvent(event);
}
}
}
}
@MainThread
private boolean emit(final NativeEvent event) {
if (!jsReady || reactContext == null || !reactContext.hasActiveCatalystInstance()) {
return false;
}
try {
reactContext.getJSModule(
DeviceEventManagerModule.RCTDeviceEventEmitter.class
).emit("rnfb_" + event.getEventName(), event.getEventBody());
} catch (Exception e) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,102 @@
package io.invertase.firebase.common;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.ProviderInfo;
import android.database.Cursor;
import android.net.Uri;
import android.support.annotation.Nullable;
import io.invertase.firebase.app.ReactNativeFirebaseApp;
public class ReactNativeFirebaseInitProvider extends ContentProvider {
/**
* Should match the {@link ReactNativeFirebaseInitProvider} authority if $androidId is empty.
*/
static final String EMPTY_APPLICATION_ID_PROVIDER_AUTHORITY =
"io.invertase.firebase.common.reactnativefirebaseinitprovider";
/**
* Check that the content provider's authority does not use the common package name. If it
* does, crash in order to alert the developer of the problem before they distribute the app.
*/
private static void checkContentProviderAuthority(ProviderInfo info) {
if (info != null) {
if (EMPTY_APPLICATION_ID_PROVIDER_AUTHORITY.equals(info.authority)) {
throw new IllegalStateException(
"Incorrect provider authority in manifest. This is most likely due to a missing "
+ "applicationId variable in application's build.gradle.");
}
}
}
@Override
public void attachInfo(Context context, ProviderInfo info) {
checkContentProviderAuthority(info);
super.attachInfo(context, info);
}
/**
* Called before {@link Application#onCreate()}.
*/
@Override
public boolean onCreate() {
Context applicationContext = getContext();
if (applicationContext != null && applicationContext.getApplicationContext() != null) {
applicationContext = applicationContext.getApplicationContext();
}
ReactNativeFirebaseApp.setApplicationContext(applicationContext);
return false;
}
@Nullable
@Override
public Cursor query(
Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder
) {
return null;
}
@Nullable
@Override
public String getType(Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return 0;
}
}

View File

@@ -0,0 +1,88 @@
package io.invertase.firebase.common;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import android.app.Activity;
import android.content.Context;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.WritableMap;
import java.util.HashMap;
import java.util.Map;
import io.invertase.firebase.interfaces.ContextProvider;
public class ReactNativeFirebaseModule extends ReactContextBaseJavaModule implements ContextProvider {
private String moduleName;
public ReactNativeFirebaseModule(
ReactApplicationContext reactContext,
String moduleName
) {
super(reactContext);
this.moduleName = moduleName;
}
@Override
public void initialize() {
super.initialize();
}
public ReactContext getContext() {
return getReactApplicationContext();
}
public Context getApplicationContext() {
return getReactApplicationContext().getApplicationContext();
}
public Activity getActivity() {
return getCurrentActivity();
}
public WritableMap getExceptionMap(Exception exception) {
WritableMap exceptionMap = Arguments.createMap();
String code = "unknown";
String message = exception.getMessage();
exceptionMap.putString("code", code);
exceptionMap.putString("nativeErrorCode", code);
exceptionMap.putString("message", message);
exceptionMap.putString("nativeErrorMessage", message);
return exceptionMap;
}
public void rejectPromiseWithExceptionMap(Promise promise, Exception exception) {
// TODO hook into crashlytics - report as handled exception?
promise.reject(exception, getExceptionMap(exception));
}
@Override
public String getName() {
return "RNFB" + moduleName + "Module";
}
@Override
public Map<String, Object> getConstants() {
return new HashMap<>();
}
}

View File

@@ -0,0 +1,62 @@
package io.invertase.firebase.common;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import android.content.Context;
import android.content.SharedPreferences;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import io.invertase.firebase.app.ReactNativeFirebaseApp;
public class ReactNativeFirebasePreferences {
private static final String PREFERENCES_FILE = "io.invertase.firebase";
private static ReactNativeFirebasePreferences sharedInstance = new ReactNativeFirebasePreferences();
private SharedPreferences preferences;
public static ReactNativeFirebasePreferences getSharedInstance() {
return sharedInstance;
}
public void setBooleanValue(String key, boolean value) {
getPreferences().edit().putBoolean(key, value).apply();
}
public boolean getBooleanValue(String key) {
return getPreferences().getBoolean(key, false);
}
public WritableMap getAllAsWritableMap() {
// TODO: Salakar: convert to writableMap
return Arguments.createMap();
}
public void clearAll() {
getPreferences().edit().clear().apply();
}
private SharedPreferences getPreferences() {
if (preferences == null) {
preferences = ReactNativeFirebaseApp
.getApplicationContext()
.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);
}
return preferences;
}
}

View File

@@ -0,0 +1,201 @@
package io.invertase.firebase.common;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import android.app.ActivityManager;
import android.content.Context;
import android.provider.Settings;
import android.util.Log;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import io.invertase.firebase.app.ReactNativeFirebaseApp;
@SuppressWarnings("WeakerAccess")
public class SharedUtils {
private static final String TAG = "Utils";
private static final String RN_DEVSUPPORT_CLASS = "DevSupportManagerImpl";
private static final String RN_DEVSUPPORT_PACKAGE = "com.facebook.react.devsupport";
private static final String EXPO_REGISTRY_CLASS = "ModuleRegistry";
private static final String EXPO_CORE_PACKAGE = "expo.core";
private static final String FLUTTER_REGISTRY_CLASS = "PluginRegistry";
private static final String FLUTTER_CORE_PACKAGE = "io.flutter.plugin.common";
private static final String REACT_NATIVE_REGISTRY_CLASS = "NativeModuleRegistry";
private static final String REACT_NATIVE_CORE_PACKAGE = "com.facebook.react.bridge";
private static final String FIREBASE_TEST_LAB = "firebase.test.lab";
public static String timestampToUTC(long timestamp) {
Calendar calendar = Calendar.getInstance();
Date date = new Date((timestamp + calendar.getTimeZone().getOffset(timestamp)) * 1000);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
return format.format(date);
}
/**
* send a JS event
**/
public static void sendEvent(final ReactContext context, final String eventName, Object body) {
if (context != null) {
context
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, body);
} else {
Log.d(TAG, "Missing context - cannot send event!");
}
}
/**
* We need to check if app is in foreground otherwise the app will crash.
* http://stackoverflow.com/questions/8489993/check-android-application-is-in-foreground-or-not
*
* @param context Context
* @return boolean
*/
public static boolean isAppInForeground(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (activityManager == null) return false;
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses == null) return false;
final String packageName = context.getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (
appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
&& appProcess.processName.equals(packageName)
) {
ReactContext reactContext;
try {
reactContext = (ReactContext) context;
} catch (ClassCastException exception) {
// Not react context so default to true
return true;
}
return reactContext.getLifecycleState() == LifecycleState.RESUMED;
}
}
return false;
}
public static int getResId(Context ctx, String resName) {
int resourceId = ctx
.getResources()
.getIdentifier(resName, "string", ctx.getPackageName());
if (resourceId == 0) {
Log.e(TAG, "resource " + resName + " could not be found");
}
return resourceId;
}
/**
* Is this app running in Firebase Test Lab
*
* @return Boolean
*/
public static Boolean isFirebaseTestLab() {
String testLabSetting =
Settings.System.getString(
ReactNativeFirebaseApp.getApplicationContext().getContentResolver(),
FIREBASE_TEST_LAB
);
return "true".equals(testLabSetting);
}
/**
* Checks for dev support availability - so we can ignore in release builds for example.
*
* @return Boolean
*/
public static Boolean reactNativeHasDevSupport() {
return hasPackageClass(RN_DEVSUPPORT_PACKAGE, RN_DEVSUPPORT_CLASS);
}
/**
* Is the build platform Expo?
*
* @return Boolean
*/
public static Boolean isExpo() {
return hasPackageClass(EXPO_CORE_PACKAGE, EXPO_REGISTRY_CLASS);
}
/**
* Is the build platform Flutter?
*
* @return Boolean
*/
public static Boolean isFlutter() {
return hasPackageClass(FLUTTER_CORE_PACKAGE, FLUTTER_REGISTRY_CLASS);
}
/**
* Is the build platform React Native?
*
* @return Boolean
*/
public static Boolean isReactNative() {
return !isExpo() && hasPackageClass(REACT_NATIVE_CORE_PACKAGE, REACT_NATIVE_REGISTRY_CLASS);
}
/**
* Returns true/false if a class for a package exists in the app class bundle
*
* @param packageName
* @param className
* @return
*/
@SuppressWarnings("StringBufferReplaceableByString")
public static Boolean hasPackageClass(String packageName, String className) {
// ProGuard is surprisingly smart in this case and will keep a class if it detects a call to
// Class.forName() with a static string. So instead we generate a quasi-dynamic string to
// confuse it.
String fullName = new StringBuilder(packageName)
.append(".")
.append(className)
.toString();
try {
Class.forName(fullName);
return true;
} catch (Exception e) {
return false;
}
}
}

View File

@@ -0,0 +1,29 @@
package io.invertase.firebase.interfaces;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import android.app.Activity;
import android.content.Context;
import com.facebook.react.bridge.ReactContext;
public interface ContextProvider {
Activity getActivity();
ReactContext getContext();
Context getApplicationContext();
}

View File

@@ -0,0 +1,28 @@
package io.invertase.firebase.interfaces;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import com.facebook.react.bridge.WritableMap;
public interface NativeError {
String getErrorCode();
String getErrorMessage();
String getFirebaseAppName();
String getFirebaseServiceName();
WritableMap getUserInfo();
}

View File

@@ -0,0 +1,27 @@
package io.invertase.firebase.interfaces;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import com.facebook.react.bridge.WritableMap;
public interface NativeEvent {
String getEventName();
WritableMap getEventBody();
String getFirebaseAppName();
}