diff --git a/lib/firebase.js b/lib/firebase.js index bbddff42..810957d6 100644 --- a/lib/firebase.js +++ b/lib/firebase.js @@ -35,6 +35,17 @@ class FirebaseCore { INTERNALS.APPS[app.name] = new FirebaseApp(app.name, options); INTERNALS.APPS[app.name]._initializeApp(true); } + + // modules + this.admob = this._appNamespaceOrStatics('admob', AdMobStatics, AdMob); + this.auth = this._appNamespaceOrStatics('auth', AuthStatics, Auth); + this.analytics = this._appNamespaceOrStatics('analytics', {}, Analytics); + this.config = this._appNamespaceOrStatics('config', {}, RemoteConfig); + this.crash = this._appNamespaceOrStatics('crash', {}, Crash); + this.database = this._appNamespaceOrStatics('database', DatabaseStatics, Database); + this.messaging = this._appNamespaceOrStatics('messaging', MessagingStatics, Messaging); + this.perf = this._appNamespaceOrStatics('perf', DatabaseStatics, Performance); + this.storage = this._appNamespaceOrStatics('storage', StorageStatics, Storage); } /** @@ -45,33 +56,50 @@ class FirebaseCore { * @return {*} */ initializeApp(options: Object = {}, name: string): FirebaseApp { - if (!isObject(options)) { - throw new Error(INTERNALS.STRINGS.ERROR_INIT_OBJECT); - } - - // todo validate required options - // todo required: - /* - appProps.put("apiKey", appOptions.getApiKey()); - appProps.put("applicationId", appOptions.getApplicationId()); - appProps.put("databaseUrl", appOptions.getDatabaseUrl()); - appProps.put("messagingSenderId", appOptions.getGcmSenderId()); - appProps.put("projectId", appOptions.getProjectId()); - appProps.put("storageBucket", appOptions.getStorageBucket()); - */ - if (name && !isString(name)) { throw new Error(INTERNALS.STRINGS.ERROR_INIT_STRING_NAME); } const _name = (name || INTERNALS.STRINGS.DEFAULT_APP_NAME).toUpperCase(); - if (!INTERNALS.APPS[_name]) { - INTERNALS.APPS[_name] = new FirebaseApp(_name, options); - // only initialize if certain props are available - if (options.databaseURL && options.apiKey) { - INTERNALS.APPS[_name]._initializeApp(); - } + // return an existing app if found + if (INTERNALS.APPS[_name]) return INTERNALS.APPS[_name]; + + // only validate if app doesn't already exist + // to allow apps already initialized natively + // to still go through init without erroring (backwards compatibility) + if (!isObject(options)) { + throw new Error(INTERNALS.STRINGS.ERROR_INIT_OBJECT); + } + + if (!options.apiKey) { + throw new Error(INTERNALS.STRINGS.ERROR_MISSING_OPT('apiKey')); + } + + if (!options.appId) { + throw new Error(INTERNALS.STRINGS.ERROR_MISSING_OPT('appId')); + } + + if (!options.databaseURL) { + throw new Error(INTERNALS.STRINGS.ERROR_MISSING_OPT('databaseURL')); + } + + if (!options.messagingSenderId) { + throw new Error(INTERNALS.STRINGS.ERROR_MISSING_OPT('messagingSenderId')); + } + + if (!options.projectId) { + throw new Error(INTERNALS.STRINGS.ERROR_MISSING_OPT('projectId')); + } + + if (!options.storageBucket) { + throw new Error(INTERNALS.STRINGS.ERROR_MISSING_OPT('storageBucket')); + } + + INTERNALS.APPS[_name] = new FirebaseApp(_name, options); + // only initialize if certain props are available + if (options.databaseURL && options.apiKey) { + INTERNALS.APPS[_name]._initializeApp(); } return INTERNALS.APPS[_name]; @@ -108,6 +136,13 @@ class FirebaseCore { 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 @@ -117,52 +152,9 @@ class FirebaseCore { return FirebaseCoreModule.googleApiAvailability || { isAvailable: true, status: 0 }; } - /* - * MODULES - */ - - get admob() { - return this._appNamespaceOrStatics('admob', AdMobStatics, AdMob); - } - - get auth() { - return this._appNamespaceOrStatics('auth', AuthStatics, Auth); - } - - get analytics() { - return this._appNamespaceOrStatics('analytics', {}, Analytics); - } - - get config() { - return this._appNamespaceOrStatics('config', {}, RemoteConfig); - } - - get crash() { - return this._appNamespaceOrStatics('crash', {}, Crash); - } - - - get database() { - return this._appNamespaceOrStatics('database', DatabaseStatics, Database); - } - - get messaging() { - return this._appNamespaceOrStatics('messaging', MessagingStatics, Messaging); - } - - get perf() { - return this._appNamespaceOrStatics('perf', DatabaseStatics, Performance); - } - - get storage() { - return this._appNamespaceOrStatics('storage', StorageStatics, Storage); - } - - /* * CONFIG METHODS */ - /** * Set the global logging level for all logs. * diff --git a/lib/internals.js b/lib/internals.js index 02a96dbe..088c6648 100644 --- a/lib/internals.js +++ b/lib/internals.js @@ -33,6 +33,15 @@ export default { return `The [${appName}] firebase app has not been initialized!`; }, + /** + * @param optName + * @return {string} + * @constructor + */ + ERROR_MISSING_OPT(optName) { + return `Failed to initialize app. FirebaseOptions missing or invalid '${optName}' property.`; + }, + /** * @return {string} */ diff --git a/lib/modules/storage/index.js b/lib/modules/storage/index.js index 1718bfd6..5cc4fb0a 100644 --- a/lib/modules/storage/index.js +++ b/lib/modules/storage/index.js @@ -3,7 +3,6 @@ import { NativeModules } from 'react-native'; import StorageRef from './reference'; import ModuleBase from './../../utils/ModuleBase'; -import INTERNALS from './../../internals'; const FirebaseStorage = NativeModules.RNFirebaseStorage; diff --git a/lib/utils/ModuleBase.js b/lib/utils/ModuleBase.js index 9759733d..25f51be5 100644 --- a/lib/utils/ModuleBase.js +++ b/lib/utils/ModuleBase.js @@ -27,6 +27,13 @@ const NATIVE_MODULE_EVENTS = { }; export default class ModuleBase { + /** + * + * @param firebaseApp + * @param options + * @param moduleName + * @param withEventEmitter + */ constructor(firebaseApp, options, moduleName, withEventEmitter = false) { this._options = Object.assign({}, options); this._module = moduleName; @@ -62,7 +69,7 @@ export default class ModuleBase { * @private */ _setupEventEmitter(nativeModule, moduleName) { - this._eventEmitter = FirebaseCore._getOrSetNativeEmitter(this._appName, nativeModule); + this._eventEmitter = FirebaseCore._getOrSetNativeEmitter(`${this._appName}-${this._module}`, nativeModule); const events = NATIVE_MODULE_EVENTS[moduleName]; if (events && events.length) {