From a26b6df623b9582265d449407482216da82e871e Mon Sep 17 00:00:00 2001 From: Salakar Date: Fri, 6 Oct 2017 21:45:54 +0100 Subject: [PATCH 01/18] [android][firestore] changes in type detection, as suggested by @mirkonasato --- .../firebase/firestore/FirestoreSerialize.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java b/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java index 6a0ef635..9df68623 100644 --- a/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java +++ b/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java @@ -8,7 +8,6 @@ import com.google.firebase.firestore.DocumentSnapshot; import com.google.firebase.firestore.QuerySnapshot; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Map; @@ -155,11 +154,9 @@ public class FirestoreSerialize { writableArray.pushDouble(((Float) item).doubleValue()); } else if (itemClass == String.class) { writableArray.pushString(item.toString()); - } else if (itemClass == Map.class) { + } else if (Map.class.isAssignableFrom(itemClass)) { writableArray.pushMap((objectMapToWritable((Map) item))); - } else if (itemClass == Arrays.class) { - writableArray.pushArray(objectArrayToWritable((Object[]) item)); - } else if (itemClass == List.class || itemClass == ArrayList.class) { + } else if (List.class.isAssignableFrom(itemClass)) { List list = (List) item; Object[] listAsArray = list.toArray(new Object[list.size()]); writableArray.pushArray(objectArrayToWritable(listAsArray)); @@ -194,11 +191,9 @@ public class FirestoreSerialize { map.putDouble(key, ((Float) value).doubleValue()); } else if (valueClass == String.class) { map.putString(key, value.toString()); - } else if (valueClass == Map.class) { + } else if (Map.class.isAssignableFrom(valueClass)) { map.putMap(key, (objectMapToWritable((Map) value))); - } else if (valueClass == Arrays.class) { - map.putArray(key, objectArrayToWritable((Object[]) value)); - } else if (valueClass == List.class || valueClass == ArrayList.class) { + } else if (List.class.isAssignableFrom(valueClass)) { List list = (List) value; Object[] array = list.toArray(new Object[list.size()]); map.putArray(key, objectArrayToWritable(array)); From b88d89b196e450846a19e9058e6391822f2dba46 Mon Sep 17 00:00:00 2001 From: Salakar Date: Fri, 6 Oct 2017 22:37:27 +0100 Subject: [PATCH 02/18] [android][firestore] log type rather than value on error --- .../io/invertase/firebase/firestore/FirestoreSerialize.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java b/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java index 9df68623..6ab033ae 100644 --- a/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java +++ b/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java @@ -7,7 +7,6 @@ import com.google.firebase.firestore.DocumentChange; import com.google.firebase.firestore.DocumentSnapshot; import com.google.firebase.firestore.QuerySnapshot; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -161,7 +160,7 @@ public class FirestoreSerialize { Object[] listAsArray = list.toArray(new Object[list.size()]); writableArray.pushArray(objectArrayToWritable(listAsArray)); } else { - throw new RuntimeException("Cannot convert object of type " + item); + throw new RuntimeException("Cannot convert object of type " + itemClass); } } @@ -198,7 +197,7 @@ public class FirestoreSerialize { Object[] array = list.toArray(new Object[list.size()]); map.putArray(key, objectArrayToWritable(array)); } else { - throw new RuntimeException("Cannot convert object of type " + value); + throw new RuntimeException("Cannot convert object of type " + valueClass); } } } From a090bd3480e498ef8e90c1a092f134bd098a7053 Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 00:24:00 +0100 Subject: [PATCH 03/18] [android][utils] new utils() module - home of all non firebase utilities and library configuration options, including play services availability checks --- .../invertase/firebase/RNFirebaseModule.java | 77 +++++----- lib/firebase-app.js | 2 + lib/firebase.js | 42 +----- lib/modules/utils/index.js | 135 ++++++++++++++++++ 4 files changed, 182 insertions(+), 74 deletions(-) create mode 100644 lib/modules/utils/index.js diff --git a/android/src/main/java/io/invertase/firebase/RNFirebaseModule.java b/android/src/main/java/io/invertase/firebase/RNFirebaseModule.java index 9a778357..9a38c745 100644 --- a/android/src/main/java/io/invertase/firebase/RNFirebaseModule.java +++ b/android/src/main/java/io/invertase/firebase/RNFirebaseModule.java @@ -1,22 +1,23 @@ package io.invertase.firebase; +import android.util.Log; import android.app.Activity; +import android.content.IntentSender; -import java.util.ArrayList; -import java.util.List; import java.util.Map; +import java.util.List; import java.util.HashMap; +import java.util.ArrayList; // react -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.Callback; +import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.LifecycleEventListener; +import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; // play services import com.google.android.gms.common.ConnectionResult; @@ -25,7 +26,7 @@ import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; @SuppressWarnings("WeakerAccess") -public class RNFirebaseModule extends ReactContextBaseJavaModule implements LifecycleEventListener { +public class RNFirebaseModule extends ReactContextBaseJavaModule { private static final String TAG = "RNFirebase"; public RNFirebaseModule(ReactApplicationContext reactContext) { @@ -42,12 +43,12 @@ public class RNFirebaseModule extends ReactContextBaseJavaModule implements Life public void initializeApp(String appName, ReadableMap options, Callback callback) { FirebaseOptions.Builder builder = new FirebaseOptions.Builder(); - builder.setApplicationId(options.getString("appId")); - builder.setGcmSenderId(options.getString("messagingSenderId")); builder.setApiKey(options.getString("apiKey")); + builder.setApplicationId(options.getString("appId")); builder.setProjectId(options.getString("projectId")); builder.setDatabaseUrl(options.getString("databaseURL")); builder.setStorageBucket(options.getString("storageBucket")); + builder.setGcmSenderId(options.getString("messagingSenderId")); // todo firebase sdk has no client id setter FirebaseApp.initializeApp(getReactApplicationContext(), builder.build(), appName); @@ -84,8 +85,9 @@ public class RNFirebaseModule extends ReactContextBaseJavaModule implements Life result.putBoolean("isAvailable", true); } else { result.putBoolean("isAvailable", false); - result.putBoolean("isUserResolvableError", gapi.isUserResolvableError(status)); result.putString("error", gapi.getErrorString(status)); + result.putBoolean("isUserResolvableError", gapi.isUserResolvableError(status)); + result.putBoolean("hasResolution", new ConnectionResult(status).hasResolution()); } return result; } @@ -94,7 +96,7 @@ public class RNFirebaseModule extends ReactContextBaseJavaModule implements Life * Prompt the device user to update play services */ @ReactMethod - public void promptPlayServices() { + public void promptForPlayServices() { GoogleApiAvailability gapi = GoogleApiAvailability.getInstance(); int status = gapi.isGooglePlayServicesAvailable(getReactApplicationContext()); @@ -106,6 +108,27 @@ public class RNFirebaseModule extends ReactContextBaseJavaModule implements Life } } + /** + * Prompt the device user to update play services + */ + @ReactMethod + public void resolutionForPlayServices() { + int status = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(getReactApplicationContext()); + ConnectionResult connectionResult = new ConnectionResult(status); + + if (!connectionResult.isSuccess() && connectionResult.hasResolution()) { + Activity activity = getCurrentActivity(); + 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 */ @@ -122,32 +145,16 @@ public class RNFirebaseModule extends ReactContextBaseJavaModule implements Life } } - @Override - public void onHostResume() { -// WritableMap params = Arguments.createMap(); -// params.putBoolean("isForeground", true); -// Utils.sendEvent(getReactApplicationContext(), "RNFirebaseAppState", params); - } - - @Override - public void onHostPause() { -// WritableMap params = Arguments.createMap(); -// params.putBoolean("isForeground", false); -// Utils.sendEvent(getReactApplicationContext(), "RNFirebaseAppState", params); - } - - @Override - public void onHostDestroy() { - - } @Override public Map getConstants() { FirebaseApp firebaseApp; - Map constants = new HashMap<>(); - List firebaseAppList = FirebaseApp.getApps(getReactApplicationContext()); - List> appMapsList = new ArrayList>(); + Map constants = new HashMap<>(); + List> appMapsList = new ArrayList<>(); + List firebaseAppList = FirebaseApp.getApps(getReactApplicationContext()); + + // TODO no way to get client id currently from app options - firebase sdk issue for (FirebaseApp app : firebaseAppList) { String appName = app.getName(); FirebaseOptions appOptions = app.getOptions(); @@ -156,16 +163,16 @@ public class RNFirebaseModule extends ReactContextBaseJavaModule implements Life appProps.put("name", appName); appProps.put("apiKey", appOptions.getApiKey()); appProps.put("appId", appOptions.getApplicationId()); + appProps.put("projectId", appOptions.getProjectId()); appProps.put("databaseURL", appOptions.getDatabaseUrl()); appProps.put("messagingSenderId", appOptions.getGcmSenderId()); - appProps.put("projectId", appOptions.getProjectId()); appProps.put("storageBucket", appOptions.getStorageBucket()); - // TODO no way to get client id currently from app options - firebase sdk issue + appMapsList.add(appProps); } constants.put("apps", appMapsList); - constants.put("googleApiAvailability", getPlayServicesStatus()); + constants.put("playServicesAvailability", getPlayServicesStatus()); return constants; } } diff --git a/lib/firebase-app.js b/lib/firebase-app.js index 4f451203..1a4742e9 100644 --- a/lib/firebase-app.js +++ b/lib/firebase-app.js @@ -13,6 +13,7 @@ import Storage, { statics as StorageStatics } from './modules/storage'; import Database, { statics as DatabaseStatics } from './modules/database'; import Messaging, { statics as MessagingStatics } from './modules/messaging'; import Firestore, { statics as FirestoreStatics } from './modules/firestore'; +import Utils, { statics as UtilsStatics } from './modules/utils'; const FirebaseCoreModule = NativeModules.RNFirebase; @@ -37,6 +38,7 @@ export default class FirebaseApp { this.messaging = this._staticsOrModuleInstance(MessagingStatics, Messaging); this.perf = this._staticsOrModuleInstance({}, Performance); this.storage = this._staticsOrModuleInstance(StorageStatics, Storage); + this.utils = this._staticsOrModuleInstance(UtilsStatics, Utils); this._extendedProps = {}; } diff --git a/lib/firebase.js b/lib/firebase.js index c67b4f8f..ee8d3ddb 100644 --- a/lib/firebase.js +++ b/lib/firebase.js @@ -4,11 +4,9 @@ */ import { NativeModules, NativeEventEmitter } from 'react-native'; -import { isObject, isString } from './utils'; - import INTERNALS from './internals'; -import PACKAGE from './../package.json'; import FirebaseApp from './firebase-app'; +import { isObject, isString } from './utils'; // module imports import AdMob, { statics as AdMobStatics } from './modules/admob'; @@ -21,6 +19,7 @@ import Storage, { statics as StorageStatics } from './modules/storage'; import Database, { statics as DatabaseStatics } from './modules/database'; import Messaging, { statics as MessagingStatics } from './modules/messaging'; import Firestore, { statics as FirestoreStatics } from './modules/firestore'; +import Utils, { statics as UtilsStatics } from './modules/utils'; const FirebaseCoreModule = NativeModules.RNFirebase; @@ -52,6 +51,7 @@ class FirebaseCore { this.messaging = this._appNamespaceOrStatics(MessagingStatics, Messaging); this.perf = this._appNamespaceOrStatics(DatabaseStatics, Performance); this.storage = this._appNamespaceOrStatics(StorageStatics, Storage); + this.utils = this._appNamespaceOrStatics(UtilsStatics, Utils); } /** @@ -139,42 +139,6 @@ class FirebaseCore { return Object.values(INTERNALS.APPS); } - /** - * The current RNFirebase SDK version. - */ - get SDK_VERSION() { - return PACKAGE.version; - } - - /** - * The platform specific default app name - */ - get DEFAULT_APP_NAME() { - return INTERNALS.STRINGS.DEFAULT_APP_NAME; - } - - /** - * Returns props from the android GoogleApiAvailability sdk - * @android - * @return {RNFirebase.GoogleApiAvailabilityType|{isAvailable: boolean, status: number}} - */ - get googleApiAvailability(): GoogleApiAvailabilityType { - return FirebaseCoreModule.googleApiAvailability || { isAvailable: true, status: 0 }; - } - - /* - * CONFIG METHODS - */ - /** - * Set the global logging level for all logs. - * - * @param booleanOrDebugString - */ - setLogLevel(booleanOrDebugString) { - INTERNALS.OPTIONS.logLevel = booleanOrDebugString; - Log.setLevel(booleanOrDebugString); - } - /* * INTERNALS */ diff --git a/lib/modules/utils/index.js b/lib/modules/utils/index.js new file mode 100644 index 00000000..333cabd1 --- /dev/null +++ b/lib/modules/utils/index.js @@ -0,0 +1,135 @@ +// @flow +import { NativeModules } from 'react-native'; +import { version as ReactVersion } from 'react'; +import ReactNativeVersion from 'react-native/Libraries/Core/ReactNativeVersion'; + +import INTERNALS from './../../internals'; +import { isIOS } from './../../utils'; +import PACKAGE from './../../../package.json'; + +const FirebaseCoreModule = NativeModules.RNFirebase; + +export default class RNFirebaseUtils { + static _NAMESPACE = 'utils'; + static _NATIVE_DISABLED = true; + static _NATIVE_MODULE = 'RNFirebaseUtils'; + + /** + * + */ + checkPlayServicesAvailability() { + if (isIOS) return null; + if (!this.playServicesAvailability.isAvailable) { + if (INTERNALS.OPTIONS.promptOnMissingPlayServices && this.playServicesAvailability.isUserResolvableError) { + this.promptForPlayServices(); + } else { + const error = INTERNALS.STRINGS.ERROR_PLAY_SERVICES(this.playServicesAvailability.code); + if (INTERNALS.OPTIONS.errorOnMissingPlayServices) { + throw new Error(error); + } else { + console.warn(error); + } + } + } + + return null; + } + + promptForPlayServices() { + if (isIOS) return null; + return FirebaseCoreModule.promptForPlayServices(); + } + + resolutionForPlayServices() { + if (isIOS) return null; + return FirebaseCoreModule.resolutionForPlayServices(); + } + + makePlayServicesAvailable() { + if (isIOS) return null; + return FirebaseCoreModule.makePlayServicesAvailable(); + } + + + get sharedEventEmitter(): Object { + return INTERNALS.SharedEventEmitter; + } + + /** + * Set the global logging level for all logs. + * + * @param booleanOrDebugString + */ + set logLevel(booleanOrDebugString) { + INTERNALS.OPTIONS.logLevel = booleanOrDebugString; + } + + + /** + * Returns an array of all current database registrations id strings + */ + get databaseRegistrations(): Array { + return Object.keys(INTERNALS.SyncTree._reverseLookup); + } + + /** + * Call with a registration id string to get the details off this reg + */ + get getDatabaseRegistrationDetails(): Function { + return INTERNALS.SyncTree.getRegistration.bind(INTERNALS.SyncTree); + } + + /** + * Accepts an array or a single string of registration ids. + * This will remove the refs on both the js and native sides and their listeners. + * @return {function(this:T)} + */ + get removeDatabaseRegistration(): Function { + return INTERNALS.SyncTree.removeListenersForRegistrations.bind(INTERNALS.SyncTree); + } + + /** + * The platform specific default app name + */ + get DEFAULT_APP_NAME() { + return INTERNALS.STRINGS.DEFAULT_APP_NAME; + } + + /** + * Returns props from the android GoogleApiAvailability sdk + * @android + * @return {RNFirebase.GoogleApiAvailabilityType|{isAvailable: boolean, status: number}} + */ + get playServicesAvailability(): GoogleApiAvailabilityType { + return FirebaseCoreModule.playServicesAvailability || { isAvailable: true, status: 0 }; + } + + /** + * Enable/Disable automatic prompting of the play services update dialog + * @android + * @param bool + */ + set errorOnMissingPlayServices(bool: Boolean) { + INTERNALS.OPTIONS.errorOnMissingPlayServices = bool; + } + + /** + * Enable/Disable automatic prompting of the play services update dialog + * @android + * @param bool + */ + set promptOnMissingPlayServices(bool: Boolean) { + INTERNALS.OPTIONS.promptOnMissingPlayServices = bool; + } +} + + +export const statics = { + DEFAULT_APP_NAME: INTERNALS.STRINGS.DEFAULT_APP_NAME, + VERSIONS: { + react: ReactVersion, + 'react-native': Object.values(ReactNativeVersion.version).slice(0, 3).join('.'), + 'react-native-firebase': PACKAGE.version, + }, +}; + From 08fae27f70209cd3049b7312352aa739e4b74809 Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 01:31:32 +0100 Subject: [PATCH 04/18] [flow] update GoogleApiAvailabilityType to include 'hasResolution' --- lib/flow.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/flow.js b/lib/flow.js index a96e34b3..f5295758 100644 --- a/lib/flow.js +++ b/lib/flow.js @@ -35,6 +35,7 @@ declare type GoogleApiAvailabilityType = { status: number, isAvailable: boolean, isUserResolvableError?: boolean, + hasResolution?: boolean, error?: string }; From 3d360348d5d346e6e081608be9b3735b635afb61 Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 01:49:12 +0100 Subject: [PATCH 05/18] [utils] run play services check automatically after any module usage - once --- lib/firebase.js | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/lib/firebase.js b/lib/firebase.js index ee8d3ddb..2ce9317c 100644 --- a/lib/firebase.js +++ b/lib/firebase.js @@ -6,7 +6,7 @@ import { NativeModules, NativeEventEmitter } from 'react-native'; import INTERNALS from './internals'; import FirebaseApp from './firebase-app'; -import { isObject, isString } from './utils'; +import { isObject, isString, isAndroid } from './utils'; // module imports import AdMob, { statics as AdMobStatics } from './modules/admob'; @@ -27,18 +27,13 @@ class FirebaseCore { constructor() { this._nativeEmitters = {}; this._nativeSubscriptions = {}; + this._checkedPlayServices = false; if (!FirebaseCoreModule) { throw (new Error(INTERNALS.STRINGS.ERROR_MISSING_CORE)); } - for (let i = 0, len = FirebaseCoreModule.apps.length; i < len; i++) { - const app = FirebaseCoreModule.apps[i]; - const options = Object.assign({}, app); - delete options.name; - INTERNALS.APPS[app.name] = new FirebaseApp(app.name, options); - INTERNALS.APPS[app.name]._initializeApp(true); - } + this._initializeNativeApps(); // modules this.admob = this._appNamespaceOrStatics(AdMobStatics, AdMob); @@ -54,6 +49,20 @@ class FirebaseCore { this.utils = this._appNamespaceOrStatics(UtilsStatics, Utils); } + /** + * Bootstraps all native app instances that were discovered on boot + * @private + */ + _initializeNativeApps() { + for (let i = 0, len = FirebaseCoreModule.apps.length; i < len; i++) { + const app = FirebaseCoreModule.apps[i]; + const options = Object.assign({}, app); + delete options.name; + INTERNALS.APPS[app.name] = new FirebaseApp(app.name, options); + INTERNALS.APPS[app.name]._initializeApp(true); + } + } + /** * Web SDK initializeApp * @@ -171,7 +180,6 @@ class FirebaseCore { /** * - * @param namespace * @param statics * @param InstanceClass * @return {function(FirebaseApp=)} @@ -179,8 +187,18 @@ class FirebaseCore { */ _appNamespaceOrStatics(statics = {}, InstanceClass): Function { const namespace = InstanceClass._NAMESPACE; + + // play services checks will run for the first time on any module + // usage - except for the utils module - to allow you to configure + // play services options + if (isAndroid && namespace !== Utils._NAMESPACE && !this._checkedPlayServices) { + this._checkedPlayServices = true; + this.utils().checkPlayServicesAvailability(); + } + const getNamespace = (app?: FirebaseApp) => { let _app = app; + // throw an error if it's not a valid app instance if (_app && !(_app instanceof FirebaseApp)) throw new Error(INTERNALS.STRINGS.ERROR_NOT_APP(namespace)); @@ -193,6 +211,7 @@ class FirebaseCore { Object.assign(getNamespace, statics, { nativeModuleExists: !!NativeModules[InstanceClass._NATIVE_MODULE], }); + return getNamespace; } From 1d2549556b2deaab914d650dfeaa644c2a4a6e48 Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 01:53:05 +0100 Subject: [PATCH 06/18] [tests][android] add perf package back into initialized modules --- .../main/java/com/reactnativefirebasedemo/MainApplication.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/android/app/src/main/java/com/reactnativefirebasedemo/MainApplication.java b/tests/android/app/src/main/java/com/reactnativefirebasedemo/MainApplication.java index 4047c71c..a9ec77f6 100644 --- a/tests/android/app/src/main/java/com/reactnativefirebasedemo/MainApplication.java +++ b/tests/android/app/src/main/java/com/reactnativefirebasedemo/MainApplication.java @@ -12,6 +12,7 @@ import io.invertase.firebase.crash.RNFirebaseCrashPackage; import io.invertase.firebase.database.RNFirebaseDatabasePackage; import io.invertase.firebase.firestore.RNFirebaseFirestorePackage; import io.invertase.firebase.messaging.RNFirebaseMessagingPackage; +import io.invertase.firebase.perf.RNFirebasePerformancePackage; import io.invertase.firebase.storage.RNFirebaseStoragePackage; import com.oblador.vectoricons.VectorIconsPackage; import com.facebook.react.ReactNativeHost; @@ -44,7 +45,7 @@ public class MainApplication extends Application implements ReactApplication { new RNFirebaseDatabasePackage(), new RNFirebaseFirestorePackage(), new RNFirebaseMessagingPackage(), - // new RNFirebasePerformancePackage(), + new RNFirebasePerformancePackage(), new RNFirebaseStoragePackage() ); } From 11da976a0a24c528d9e4de4cd2e1aed0c37b00f2 Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 03:06:29 +0100 Subject: [PATCH 07/18] [internals][utils] added play services red box string creator --- lib/internals.js | 67 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/lib/internals.js b/lib/internals.js index 9d26cce7..159ba007 100644 --- a/lib/internals.js +++ b/lib/internals.js @@ -22,10 +22,43 @@ const GRADLE_DEPS = { admob: 'ads', }; +const PLAY_SERVICES_CODES = { + 1: { + code: 'SERVICE_MISSING', + message: 'Google Play services is missing on this device.', + }, + 2: { + code: 'SERVICE_VERSION_UPDATE_REQUIRED', + message: 'The installed version of Google Play services on this device is out of date.', + }, + 3: { + code: 'SERVICE_DISABLED', + message: 'The installed version of Google Play services has been disabled on this device.', + }, + 9: { + code: 'SERVICE_INVALID', + message: 'The version of the Google Play services installed on this device is not authentic.', + }, + 18: { + code: 'SERVICE_UPDATING', + message: 'Google Play services is currently being updated on this device.', + }, + 19: { + code: 'SERVICE_MISSING_PERMISSION', + message: 'Google Play service doesn\'t have one or more required permissions.', + }, +}; + export default { // default options OPTIONS: { logLevel: 'warn', + errorOnMissingPlayServices: true, + promptOnMissingPlayServices: true, + }, + + FLAGS: { + checkedPlayServices: false, }, // track all initialized firebase apps @@ -141,15 +174,15 @@ export default { /** * @return {string} */ - ERROR_UNSUPPORTED_CLASS_METHOD(classname, method) { - return `${classname}.${method}() is unsupported by the native Firebase SDKs.`; + ERROR_UNSUPPORTED_CLASS_METHOD(className, method) { + return `${className}.${method}() is unsupported by the native Firebase SDKs.`; }, /** * @return {string} */ - ERROR_UNSUPPORTED_CLASS_PROPERTY(classname, property) { - return `${classname}.${property} is unsupported by the native Firebase SDKs.`; + ERROR_UNSUPPORTED_CLASS_PROPERTY(className, property) { + return `${className}.${property} is unsupported by the native Firebase SDKs.`; }, /** @@ -159,6 +192,32 @@ export default { return `firebase.${module._NAMESPACE}().${method}() is unsupported by the native Firebase SDKs.`; }, + + /** + * @return {string} + */ + ERROR_PLAY_SERVICES(statusCode) { + const knownError = PLAY_SERVICES_CODES[statusCode]; + let start = 'Google Play Services is required to run firebase services on android but a valid installation was not found on this device.'; + + if (statusCode === 2) { + start = 'Google Play Services is out of date and may cause some firebase services like authentication to hang when used. It is recommended that you update it.'; + } + + // eslint-disable-next-line prefer-template + return `${start}\r\n\r\n` + + '-------------------------\r\n' + + (knownError ? + `${knownError.code}: ${knownError.message} (code ${statusCode})` : + `A specific play store availability reason reason was not available (unknown code: ${statusCode || null})` + ) + + '\r\n-------------------------' + + '\r\n\r\n' + + 'For more information on how to resolve this issue, configure Play Services checks or for guides on how to validate Play Services on your users devices see the link below:' + + '\r\n\r\nhttp://invertase.link/play-services'; + }, + + DEFAULT_APP_NAME, }, From 0eb38c4593f551a5366b34d06295fe64738a76e5 Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 03:07:00 +0100 Subject: [PATCH 08/18] [tests][core] fixed broken test --- tests/src/tests/core/coreTests.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/src/tests/core/coreTests.js b/tests/src/tests/core/coreTests.js index 1ab33292..6aa41bb6 100644 --- a/tests/src/tests/core/coreTests.js +++ b/tests/src/tests/core/coreTests.js @@ -48,13 +48,14 @@ function coreTests({ describe, it }) { it('it should provide an array of apps', () => { should.equal(!!RNFirebase.apps.length, true); - should.equal(RNFirebase.apps[0]._name, RNFirebase.DEFAULT_APP_NAME); + should.equal(RNFirebase.apps[0]._name, RNFirebase.utils.DEFAULT_APP_NAME); should.equal(RNFirebase.apps[0].name, '[DEFAULT]'); return Promise.resolve(); }); + // todo move to UTILS module tests it('it should provide the sdk version', () => { - should.equal(!!RNFirebase.SDK_VERSION.length, true); + should.equal(!!RNFirebase.utils.VERSIONS['react-native-firebase'].length, true); return Promise.resolve(); }); From e74b760288f08ee65698e8f0a2de975fedd1417b Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 03:09:05 +0100 Subject: [PATCH 09/18] [utils] move play services check --- lib/firebase-app.js | 7 ++++++- lib/firebase.js | 9 --------- lib/modules/utils/index.js | 8 ++++++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/firebase-app.js b/lib/firebase-app.js index 1a4742e9..d93985b9 100644 --- a/lib/firebase-app.js +++ b/lib/firebase-app.js @@ -1,7 +1,7 @@ import { NativeModules } from 'react-native'; import INTERNALS from './internals'; -import { isObject } from './utils'; +import { isObject, isAndroid } from './utils'; import AdMob, { statics as AdMobStatics } from './modules/admob'; import Auth, { statics as AuthStatics } from './modules/auth'; @@ -152,6 +152,11 @@ export default class FirebaseApp { const getInstance = () => { const _name = `_${InstanceClass._NAMESPACE}`; + if (isAndroid && InstanceClass._NAMESPACE !== Utils._NAMESPACE && !INTERNALS.FLAGS.checkedPlayServices) { + INTERNALS.FLAGS.checkedPlayServices = true; + this.utils().checkPlayServicesAvailability(); + } + if (!this._namespaces[_name]) { this._namespaces[_name] = new InstanceClass(this); } diff --git a/lib/firebase.js b/lib/firebase.js index 2ce9317c..b841a92b 100644 --- a/lib/firebase.js +++ b/lib/firebase.js @@ -27,7 +27,6 @@ class FirebaseCore { constructor() { this._nativeEmitters = {}; this._nativeSubscriptions = {}; - this._checkedPlayServices = false; if (!FirebaseCoreModule) { throw (new Error(INTERNALS.STRINGS.ERROR_MISSING_CORE)); @@ -188,14 +187,6 @@ class FirebaseCore { _appNamespaceOrStatics(statics = {}, InstanceClass): Function { const namespace = InstanceClass._NAMESPACE; - // play services checks will run for the first time on any module - // usage - except for the utils module - to allow you to configure - // play services options - if (isAndroid && namespace !== Utils._NAMESPACE && !this._checkedPlayServices) { - this._checkedPlayServices = true; - this.utils().checkPlayServicesAvailability(); - } - const getNamespace = (app?: FirebaseApp) => { let _app = app; diff --git a/lib/modules/utils/index.js b/lib/modules/utils/index.js index 333cabd1..57a9cce7 100644 --- a/lib/modules/utils/index.js +++ b/lib/modules/utils/index.js @@ -19,13 +19,17 @@ export default class RNFirebaseUtils { */ checkPlayServicesAvailability() { if (isIOS) return null; + + const code = this.playServicesAvailability.code; + if (!this.playServicesAvailability.isAvailable) { if (INTERNALS.OPTIONS.promptOnMissingPlayServices && this.playServicesAvailability.isUserResolvableError) { this.promptForPlayServices(); } else { - const error = INTERNALS.STRINGS.ERROR_PLAY_SERVICES(this.playServicesAvailability.code); + const error = INTERNALS.STRINGS.ERROR_PLAY_SERVICES(code); if (INTERNALS.OPTIONS.errorOnMissingPlayServices) { - throw new Error(error); + if (code === 2) console.warn(error); // only warn if it exists but may need an update + else throw new Error(error); } else { console.warn(error); } From f0fe05b0c6b4a0005597c172cd0b9dc81629381a Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 03:15:46 +0100 Subject: [PATCH 10/18] [utils] misc --- lib/modules/utils/index.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/modules/utils/index.js b/lib/modules/utils/index.js index 57a9cce7..29c7aa7e 100644 --- a/lib/modules/utils/index.js +++ b/lib/modules/utils/index.js @@ -54,7 +54,6 @@ export default class RNFirebaseUtils { return FirebaseCoreModule.makePlayServicesAvailable(); } - get sharedEventEmitter(): Object { return INTERNALS.SharedEventEmitter; } @@ -92,13 +91,6 @@ export default class RNFirebaseUtils { return INTERNALS.SyncTree.removeListenersForRegistrations.bind(INTERNALS.SyncTree); } - /** - * The platform specific default app name - */ - get DEFAULT_APP_NAME() { - return INTERNALS.STRINGS.DEFAULT_APP_NAME; - } - /** * Returns props from the android GoogleApiAvailability sdk * @android From fff73f3bcf8f7a7f0d8fd64a035dfd3a01a4c1ac Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 03:21:13 +0100 Subject: [PATCH 11/18] [docs] misc installation changes from @chrisbianca --- docs/installation-android.md | 39 +++++++++++++-------------- docs/installation-ios.md | 52 ++++++++++++------------------------ 2 files changed, 36 insertions(+), 55 deletions(-) diff --git a/docs/installation-android.md b/docs/installation-android.md index a6747852..08080f83 100644 --- a/docs/installation-android.md +++ b/docs/installation-android.md @@ -1,6 +1,10 @@ # Android Installation -## 1) Setup google-services.json +## 1) Link RNFirebase + +Run `react-native link react-native-firebase` + +## 2) Setup google-services.json Download the `google-services.json` file provided by Firebase in the _Add Firebase to Android_ platform menu in your Firebase configuration console. This file should be downloaded to `YOUR_PROJECT/android/app/google-services.json`. Next you'll have to add the google-services gradle plugin in order to parse it. @@ -23,28 +27,19 @@ In your app build.gradle file, add the gradle plugin at the VERY BOTTOM of the f apply plugin: 'com.google.gms.google-services' ``` -## 2) Link RNFirebase +## 3) Setup Firebase -RNFirebase is split into separate modules to allow you to only include the Firebase functionality that you need in your application. - -First add the project path to `android/settings.gradle`: - -```groovy -include ':react-native-firebase' -project(':react-native-firebase').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-firebase/android') -``` - -Now you need to include RNFirebase and the required Firebase dependencies in our `android/app/build.gradle` so that they are compiled as part of React Native. In the `dependencies` listing, add the appropriate `compile` lines: +Now you need to the required Firebase dependencies in our `android/app/build.gradle` so that they are compiled as part of React Native. In the `dependencies` listing, add the appropriate `compile` lines: ```groovy dependencies { - // RNFirebase required dependencies + // This should be added already compile(project(':react-native-firebase')) { transitive = false } - compile "com.google.firebase:firebase-core:11.4.2" - // If you are receiving Google Play API availability issues, add the following dependency + // RNFirebase required dependencies + compile "com.google.firebase:firebase-core:11.4.2" compile "com.google.android.gms:play-services-base:11.4.2" // RNFirebase optional dependencies @@ -60,7 +55,7 @@ dependencies { } ``` -Google Play services from 11.4.2 onwards require their dependencies to be downloaded from Google's Maven respository so add the +Google Play services from 11.2.0 onwards require their dependencies to be downloaded from Google's Maven respository so add the required reference to the repositories section of the *project* level build.gradle `android/build.gradle` @@ -83,13 +78,17 @@ allprojects { } ``` +## 4) Install RNFirebase modules + +RNFirebase is split into separate modules to allow you to only include the Firebase functionality that you need in your application. + To install `react-native-firebase` in your project, you'll need to import the packages you need from `io.invertase.firebase` in your project's `android/app/src/main/java/com/[app name]/MainApplication.java` and list them as packages for ReactNative in the `getPackages()` function: ```java package com.youcompany.application; // ... // Required package -import io.invertase.firebase.RNFirebasePackage; // <-- Add this line +import io.invertase.firebase.RNFirebasePackage; // <-- This should be added already // Optional packages - add as appropriate import io.invertase.firebase.admob.RNFirebaseAdMobPackage; //Firebase AdMob import io.invertase.firebase.analytics.RNFirebaseAnalyticsPackage; // Firebase Analytics @@ -109,7 +108,7 @@ public class MainApplication extends Application implements ReactApplication { protected List getPackages() { return Arrays.asList( new MainReactPackage(), - new RNFirebasePackage(), // <-- Add this line + new RNFirebasePackage(), // <-- This should be added already // Add these packages as appropriate new RNFirebaseAdMobPackage(), new RNFirebaseAnalyticsPackage(), @@ -128,7 +127,7 @@ public class MainApplication extends Application implements ReactApplication { } ``` -## 3) Cloud Messaging (optional) +## 5) Cloud Messaging (optional) If you plan on using [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging/), add the following to `android/app/src/main/AndroidManifest.xml`. @@ -179,7 +178,7 @@ If you would like to schedule local notifications then you also need to add the ``` -## 4) Performance Monitoring (optional) +## 6) Performance Monitoring (optional) If you'd like to take advantage of Firebase's [Performance Monitoring](https://firebase.google.com/docs/perf-mon/), the following additions to your project setup are required: diff --git a/docs/installation-ios.md b/docs/installation-ios.md index 6ee7d179..3c3a702c 100644 --- a/docs/installation-ios.md +++ b/docs/installation-ios.md @@ -2,10 +2,14 @@ Please note that there is a known issue when using Cocoapods with the `use_frameworks!` enabled. This is explained [here](https://github.com/invertase/react-native-firebase/issues/252#issuecomment-316340974). Unfortunately we don't currently have a workaround, but are engaging with Firebase directly to try and resolve the problem. -## 1) Setup GoogleService-Info.plist +## 1) Link RNFirebase + +Run `react-native link react-native-firebase` + +## 2) Setup GoogleService-Info.plist Setup the `GoogleService-Info.plist` file by following the instructions and adding it to the root of your project at `ios/[YOUR APP NAME]/GoogleService-Info.plist` [here](https://firebase.google.com/docs/ios/setup#add_firebase_to_your_app). -### 1.1) Initialisation +### 2.1) Initialisation Make sure you've added the following to the top of your `ios/[YOUR APP NAME]]/AppDelegate.m` file: `#import ` @@ -14,11 +18,11 @@ and this to the `didFinishLaunchingWithOptions:(NSDictionary *)launchOptions` me `[FIRApp configure];` -## 2) Setup RNFirebase +## 3) Setup Firebase Pods -Unfortunately, due to the fact that Firebase is much easier to setup using Cocoapods, *we do not recommend* `react-native link` as it is not customisable enough for our needs and we have had numerous problems reported. +Firebase recommends using Cocoapods to install the Firebase SDK. -### 2.0) If you don't already have Cocoapods set up +### 3.0) If you don't already have Cocoapods set up Follow the instructions to install Cocoapods and create your Podfile [here](https://firebase.google.com/docs/ios/setup#add_the_sdk). **NOTE: The Podfile needs to be initialised in the `ios` directory of your project. Make sure to update cocoapods libs first by running `pod update`** @@ -50,18 +54,17 @@ Follow the instructions to install Cocoapods and create your Podfile [here](http - Uncomment the `# platform :ios, '9.0'` line by removing the `#` character - Change the version as required -### 2.1) Check the Podfile platform version +### 3.1) Check the Podfile platform version We recommend using a minimum platform version of at least 9.0 for your application to ensure that the correct version of the Firebase libraries are used. To do this, you need to uncomment or make sure the following line is present at the top of your `Podfile`: `platform :ios, '9.0'` -### 2.2) Add the required pods +### 3.2) Add the required pods Simply add the following to your `Podfile` either at the top level, or within the main project target: ```ruby # Required by RNFirebase pod 'Firebase/Core' -pod 'RNFirebase', :path => '../node_modules/react-native-firebase' # [OPTIONAL PODS] - comment out pods for firebase products you won't be using. pod 'Firebase/AdMob' @@ -75,27 +78,6 @@ pod 'Firebase/RemoteConfig' pod 'Firebase/Storage' ``` -If you do not already have React and Yoga installed as pods, then add Yoga and React to your `Podfile` as follows: - -```ruby -pod "Yoga", :path => "../node_modules/react-native/ReactCommon/yoga" -pod 'React', :path => '../node_modules/react-native', :subspecs => [ - 'BatchedBridge', # Required For React Native 0.45.0+ - 'Core', - # Add any other subspecs you want to use in your project -] - -#Also add this at the very bottom of your Podfile - -post_install do |installer| - installer.pods_project.targets.each do |target| - if target.name == "React" - target.remove_from_project - end - end -end -``` - Run `pod install`. **NOTE: You need to use the `ios/[YOUR APP NAME].xcworkspace` instead of the `ios/[YOUR APP NAME].xcproj` file from now on.** @@ -106,24 +88,24 @@ Run `pod install`. **Resolution** - Run `npm install --save react-native-firebase` from the root of your project -## 3) Cloud Messaging (optional) +## 4) Cloud Messaging (optional) If you plan on using [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging/) then, you need to: **NOTE: FCM does not work on the iOS simulator, you must test is using a real device. This is a restriction enforced by Apple for some unknown reason.** -### 3.1) Set up certificates +### 4.1) Set up certificates Follow the instructions at https://firebase.google.com/docs/cloud-messaging/ios/certs -### 3.2) Enable capabilities +### 4.2) Enable capabilities In Xcode, enable the following capabilities: 1) Push Notifications 2) Background modes > Remote notifications -### 3.3) Update `AppDelegate.h` +### 4.3) Update `AppDelegate.h` Add the following import: @@ -133,7 +115,7 @@ Change the interface descriptor to: `@interface AppDelegate : UIResponder ` -### 3.4) Update `AppDelegate.m` +### 4.4) Update `AppDelegate.m` Add the following import: @@ -172,7 +154,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response } ``` -### 3.5) Debugging +### 4.5) Debugging If you're having problems with messages not being received, check out the following blog post for help: From c73cfa9bfacddb89a3a83f172917e4c00656152d Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 03:23:27 +0100 Subject: [PATCH 12/18] 3.0.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3010ee8a..8865f032 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-native-firebase", - "version": "3.0.0-alpha.5", + "version": "3.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 685b638e..74737936 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-firebase", - "version": "3.0.0", + "version": "3.0.1", "author": "Invertase (http://invertase.io)", "description": "A well tested, feature rich Firebase implementation for React Native, supporting iOS & Android. Individual module support for Admob, Analytics, Auth, Crash Reporting, Cloud Firestore, Database, Messaging (FCM), Remote Config, Storage and Performance.", "main": "index", From 10247e067dfc7d20d9e3bd5c211db4e563d7c252 Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 03:53:20 +0100 Subject: [PATCH 13/18] [utils] misc code comment --- lib/modules/utils/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/utils/index.js b/lib/modules/utils/index.js index 29c7aa7e..b3d9787d 100644 --- a/lib/modules/utils/index.js +++ b/lib/modules/utils/index.js @@ -101,7 +101,7 @@ export default class RNFirebaseUtils { } /** - * Enable/Disable automatic prompting of the play services update dialog + * Enable/Disable throwing an error or warning on detecting a play services problem * @android * @param bool */ From 4f5fdda1f0860e82dacba8949e4162ffa8366f29 Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 13:14:45 +0100 Subject: [PATCH 14/18] [utils] remove rn48 breaking support issue --- lib/modules/utils/index.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/modules/utils/index.js b/lib/modules/utils/index.js index b3d9787d..942b6af1 100644 --- a/lib/modules/utils/index.js +++ b/lib/modules/utils/index.js @@ -1,7 +1,7 @@ // @flow import { NativeModules } from 'react-native'; -import { version as ReactVersion } from 'react'; -import ReactNativeVersion from 'react-native/Libraries/Core/ReactNativeVersion'; +// import { version as ReactVersion } from 'react'; +// import ReactNativeVersion from 'react-native/Libraries/Core/ReactNativeVersion'; import INTERNALS from './../../internals'; import { isIOS } from './../../utils'; @@ -122,10 +122,10 @@ export default class RNFirebaseUtils { export const statics = { DEFAULT_APP_NAME: INTERNALS.STRINGS.DEFAULT_APP_NAME, - VERSIONS: { - react: ReactVersion, - 'react-native': Object.values(ReactNativeVersion.version).slice(0, 3).join('.'), - 'react-native-firebase': PACKAGE.version, - }, + // VERSIONS: { + // react: ReactVersion, + // 'react-native': Object.values(ReactNativeVersion.version).slice(0, 3).join('.'), + // 'react-native-firebase': PACKAGE.version, + // }, }; From d93a4a0c4810264c0d6b7c352d1a2ed864309eed Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 7 Oct 2017 13:14:56 +0100 Subject: [PATCH 15/18] 3.0.2 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8865f032..9cc0f93c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-native-firebase", - "version": "3.0.1", + "version": "3.0.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 74737936..4c2da247 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-firebase", - "version": "3.0.1", + "version": "3.0.2", "author": "Invertase (http://invertase.io)", "description": "A well tested, feature rich Firebase implementation for React Native, supporting iOS & Android. Individual module support for Admob, Analytics, Auth, Crash Reporting, Cloud Firestore, Database, Messaging (FCM), Remote Config, Storage and Performance.", "main": "index", From 9f07dfcd460bbfa1aec780dfa4f1dacbd140682e Mon Sep 17 00:00:00 2001 From: Salakar Date: Sun, 8 Oct 2017 16:36:01 +0100 Subject: [PATCH 16/18] [android][firestore] `Long` type fix: #479 --- .../io/invertase/firebase/firestore/FirestoreSerialize.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java b/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java index 6ab033ae..36ade3c4 100644 --- a/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java +++ b/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java @@ -147,6 +147,8 @@ public class FirestoreSerialize { writableArray.pushBoolean((Boolean) item); } else if (itemClass == Integer.class) { writableArray.pushDouble(((Integer) item).doubleValue()); + } else if (itemClass == Long.class) { + writableArray.pushDouble(((Long) item).doubleValue()); } else if (itemClass == Double.class) { writableArray.pushDouble((Double) item); } else if (itemClass == Float.class) { @@ -184,6 +186,8 @@ public class FirestoreSerialize { map.putBoolean(key, (Boolean) value); } else if (valueClass == Integer.class) { map.putDouble(key, ((Integer) value).doubleValue()); + } else if (valueClass == Long.class) { + map.putDouble(key, ((Long) value).doubleValue()); } else if (valueClass == Double.class) { map.putDouble(key, (Double) value); } else if (valueClass == Float.class) { From 1bc9c70fe18c00c15e87687909212e90ffef511e Mon Sep 17 00:00:00 2001 From: Michael Diarmid Date: Sun, 8 Oct 2017 18:24:34 +0100 Subject: [PATCH 17/18] Update installation-ios.md --- docs/installation-ios.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/installation-ios.md b/docs/installation-ios.md index 3c3a702c..27e12520 100644 --- a/docs/installation-ios.md +++ b/docs/installation-ios.md @@ -9,6 +9,15 @@ Run `react-native link react-native-firebase` ## 2) Setup GoogleService-Info.plist Setup the `GoogleService-Info.plist` file by following the instructions and adding it to the root of your project at `ios/[YOUR APP NAME]/GoogleService-Info.plist` [here](https://firebase.google.com/docs/ios/setup#add_firebase_to_your_app). +Adding the file into the directory doesn't automatically add the file to the iOS project. You need to then manually add it by doing the following: + +  - 2.1. Open `/ios/'project name'.xcworkspace` file via XCode +    - 2.1.1. If you've not got a `.xcworkspace` file yet then you'll need to come back to these steps after setting up your pods + pod install (step 3 on this page) + - 2.2. Right click on your project + - 2.3. Click "Add files to 'project name'" + - 2.4. Select the .plist file you copied into your project + - 2.5. Click OK + ### 2.1) Initialisation Make sure you've added the following to the top of your `ios/[YOUR APP NAME]]/AppDelegate.m` file: From bc92ace8edef9d5ae4f9e5d6af5eccb8cfca4443 Mon Sep 17 00:00:00 2001 From: Michael Diarmid Date: Sun, 8 Oct 2017 18:25:58 +0100 Subject: [PATCH 18/18] Update installation-ios.md --- docs/installation-ios.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installation-ios.md b/docs/installation-ios.md index 27e12520..d98bab6f 100644 --- a/docs/installation-ios.md +++ b/docs/installation-ios.md @@ -11,8 +11,8 @@ Setup the `GoogleService-Info.plist` file by following the instructions and addi Adding the file into the directory doesn't automatically add the file to the iOS project. You need to then manually add it by doing the following: -  - 2.1. Open `/ios/'project name'.xcworkspace` file via XCode -    - 2.1.1. If you've not got a `.xcworkspace` file yet then you'll need to come back to these steps after setting up your pods + pod install (step 3 on this page) + - 2.1. Open `/ios/'project name'.xcworkspace` file via XCode + - 2.1.1. If you've not got a `.xcworkspace` file yet then you'll need to come back to these steps after setting up your pods + pod install (step 3 on this page) - 2.2. Right click on your project - 2.3. Click "Add files to 'project name'" - 2.4. Select the .plist file you copied into your project