diff --git a/lib/firebase-app.js b/lib/firebase-app.js index 6efc1f0c..efeda6a8 100644 --- a/lib/firebase-app.js +++ b/lib/firebase-app.js @@ -1,7 +1,6 @@ import { NativeModules } from 'react-native'; import INTERNALS from './internals'; -import { capitalizeFirstLetter } from './utils'; import AdMob, { statics as AdMobStatics } from './modules/admob'; import Auth, { statics as AuthStatics } from './modules/auth'; diff --git a/lib/firebase.js b/lib/firebase.js index 5dc4882c..f38ea764 100644 --- a/lib/firebase.js +++ b/lib/firebase.js @@ -4,7 +4,7 @@ */ import { NativeModules, NativeEventEmitter } from 'react-native'; -import { isObject, isString, capitalizeFirstLetter } from './utils'; +import { isObject, isString } from './utils'; import INTERNALS from './internals'; import PACKAGE from './../package.json'; @@ -28,6 +28,10 @@ class FirebaseCore { this._nativeEmitters = {}; this._nativeSubscriptions = {}; + 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); @@ -63,9 +67,11 @@ class FirebaseCore { const _name = (name || INTERNALS.STRINGS.DEFAULT_APP_NAME).toUpperCase(); // return an existing app if found - // todo flag as deprecated - no longer need to initialize native apps // todo in v4 remove deprecation and throw an error - if (INTERNALS.APPS[_name]) return INTERNALS.APPS[_name]; + if (INTERNALS.APPS[_name]) { + console.warn(INTERNALS.STRINGS.WARN_INITIALIZE_DEPRECATION); + return INTERNALS.APPS[_name]; + } // only validate if app doesn't already exist // to allow apps already initialized natively diff --git a/lib/internals.js b/lib/internals.js index 7dba8909..6b378a25 100644 --- a/lib/internals.js +++ b/lib/internals.js @@ -5,6 +5,23 @@ import SyncTree from './utils/SyncTree'; const DEFAULT_APP_NAME = Platform.OS === 'ios' ? '__FIRAPP_DEFAULT' : '[DEFAULT]'; +const NAMESPACE_PODS = { + admob: 'Firebase/AdMob', + analytics: 'Firebase/Analytics', + auth: 'Firebase/Auth', + config: 'Firebase/RemoteConfig', + crash: 'Firebase/Crash', + database: 'Firebase/Database', + links: 'Firebase/DynamicLinks', + messaging: 'Firebase/Messaging', + perf: 'Firebase/Performance', + storage: 'Firebase/Storage', +}; + +const GRADLE_DEPS = { + admob: 'ads', +}; + export default { // default options OPTIONS: { @@ -17,15 +34,50 @@ export default { }, STRINGS: { + WARN_INITIALIZE_DEPRECATION: 'Deprecation: Calling \'initializeApp()\' for apps that are already initialised natively ' + + 'is unnecessary, use \'firebase.app()\' instead to access the already initialized default app instance.', + + /** + * @return {string} + */ + get ERROR_MISSING_CORE() { + if (Platform.OS === 'ios') { + return 'RNFirebase core module was not found natively on iOS, ensure you have ' + + 'correctly included the RNFirebase pod in your projects `Podfile` and have run `pod install`.' + + '\r\n\r\n See http://invertase.link/ios for the ios setup guide.'; + } + + return 'RNFirebase core module was not found natively on Android, ensure you have ' + + 'correctly added the RNFirebase and Firebase gradle dependencies to your `android/app/build.gradle` file.' + + '\r\n\r\n See http://invertase.link/android for the android setup guide.'; + }, + + ERROR_INIT_OBJECT: 'Firebase.initializeApp(options <-- requires a valid configuration object.', ERROR_INIT_STRING_NAME: 'Firebase.initializeApp(options, name <-- requires a valid string value.', /** - * @param moduleName * @return {string} + * @param namespace + * @param nativeModule */ - ERROR_MISSING_MODULE(moduleName) { - return `Attempted to call a method for a module that is not installed natively (${moduleName}).`; + ERROR_MISSING_MODULE(namespace, nativeModule) { + const snippet = `firebase.${namespace}()`; + if (Platform.OS === 'ios') { + return `You attempted to use a firebase module that's not installed natively on your iOS project by calling ${snippet}.` + + '\r\n\r\nEnsure you have the required Firebase iOS SDK pod for this module included in your Podfile, in this instance ' + + `confirm you've added "pod '${NAMESPACE_PODS[namespace]}'" to your Podfile` + + '\r\n\r\nSee http://invertase.link/ios for full setup instructions.'; + } + + const fbSDKDep = `'com.google.firebase:firebase-${GRADLE_DEPS[namespace] || namespace}'`; + const rnFirebasePackage = `'io.invertase.firebase.${namespace}.${nativeModule}Package'`; + const newInstance = `'new ${nativeModule}Package()'`; + return `You attempted to use a firebase module that's not installed on your Android project by calling ${snippet}.` + + `\r\n\r\nEnsure you have:\r\n\r\n1) Installed the required Firebase Android SDK dependency ${fbSDKDep} in your 'android/app/build.gradle' ` + + `file.\r\n\r\n2) Imported the ${rnFirebasePackage} module in your 'MainApplication.java' file.\r\n\r\n3) Added the ` + + `${newInstance} line inside of the RN 'getPackages()' method list.` + + '\r\n\r\nSee http://invertase.link/android for full setup instructions.'; }, /** diff --git a/lib/utils/ModuleBase.js b/lib/utils/ModuleBase.js index 2cda6291..7e965dad 100644 --- a/lib/utils/ModuleBase.js +++ b/lib/utils/ModuleBase.js @@ -58,7 +58,12 @@ export default class ModuleBase { const nativeModule = NativeModules[this.constructor._NATIVE_MODULE]; if (!nativeModule) { - throw new Error(INTERNALS.STRINGS.ERROR_MISSING_MODULE(this.constructor._NATIVE_MODULE)); + throw new Error( + INTERNALS.STRINGS.ERROR_MISSING_MODULE( + this.constructor._NAMESPACE, + this.constructor._NATIVE_MODULE, + ), + ); } // used by the modules that extend ModuleBase