mirror of
https://github.com/zhigang1992/react-native-firebase.git
synced 2026-04-24 04:24:52 +08:00
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:
69
packages/app/android/build.gradle
Normal file
69
packages/app/android/build.gradle
Normal 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")
|
||||
21
packages/app/android/expo.gradle
Normal file
21
packages/app/android/expo.gradle
Normal 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, "")
|
||||
BIN
packages/app/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
packages/app/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
packages/app/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
packages/app/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal 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
160
packages/app/android/gradlew
vendored
Normal 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
90
packages/app/android/gradlew.bat
vendored
Normal 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
|
||||
5
packages/app/android/lint.xml
Normal file
5
packages/app/android/lint.xml
Normal 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>
|
||||
1
packages/app/android/settings.gradle
Normal file
1
packages/app/android/settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = '@react-native-firebase/app'
|
||||
12
packages/app/android/src/main/AndroidManifest.xml
Normal file
12
packages/app/android/src/main/AndroidManifest.xml
Normal 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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<>();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user