diff --git a/src/modules/admob/index.js b/src/modules/admob/index.js index 8b2e039d..a1ae8c37 100644 --- a/src/modules/admob/index.js +++ b/src/modules/admob/index.js @@ -41,8 +41,8 @@ export default class AdMob extends ModuleBase { super(app, { events: NATIVE_EVENTS, moduleName: MODULE_NAME, - multiApp: false, - hasShards: false, + hasMultiAppSupport: false, + hasCustomUrlSupport: false, namespace: NAMESPACE, }); diff --git a/src/modules/analytics/index.js b/src/modules/analytics/index.js index 7e1af364..007e1c7c 100644 --- a/src/modules/analytics/index.js +++ b/src/modules/analytics/index.js @@ -33,8 +33,8 @@ export default class Analytics extends ModuleBase { constructor(app: App) { super(app, { moduleName: MODULE_NAME, - multiApp: false, - hasShards: false, + hasMultiAppSupport: false, + hasCustomUrlSupport: false, namespace: NAMESPACE, }); } diff --git a/src/modules/auth/index.js b/src/modules/auth/index.js index c3528cf6..cd80de13 100644 --- a/src/modules/auth/index.js +++ b/src/modules/auth/index.js @@ -55,8 +55,8 @@ export default class Auth extends ModuleBase { super(app, { events: NATIVE_EVENTS, moduleName: MODULE_NAME, - multiApp: true, - hasShards: false, + hasMultiAppSupport: true, + hasCustomUrlSupport: false, namespace: NAMESPACE, }); this._user = null; diff --git a/src/modules/config/index.js b/src/modules/config/index.js index aa5e8a42..97efdb12 100644 --- a/src/modules/config/index.js +++ b/src/modules/config/index.js @@ -36,8 +36,8 @@ export default class RemoteConfig extends ModuleBase { constructor(app: App) { super(app, { moduleName: MODULE_NAME, - multiApp: false, - hasShards: false, + hasMultiAppSupport: false, + hasCustomUrlSupport: false, namespace: NAMESPACE, }); this._developerModeEnabled = false; diff --git a/src/modules/crashlytics/index.js b/src/modules/crashlytics/index.js index 0f97a144..77c25705 100644 --- a/src/modules/crashlytics/index.js +++ b/src/modules/crashlytics/index.js @@ -14,8 +14,8 @@ export default class Crashlytics extends ModuleBase { constructor(app: App) { super(app, { moduleName: MODULE_NAME, - multiApp: false, - hasShards: false, + hasMultiAppSupport: false, + hasCustomUrlSupport: false, namespace: NAMESPACE, }); } diff --git a/src/modules/database/index.js b/src/modules/database/index.js index fb86f3b6..38807c66 100644 --- a/src/modules/database/index.js +++ b/src/modules/database/index.js @@ -48,8 +48,8 @@ export default class Database extends ModuleBase { { events: NATIVE_EVENTS, moduleName: MODULE_NAME, - multiApp: true, - hasShards: true, + hasMultiAppSupport: true, + hasCustomUrlSupport: true, namespace: NAMESPACE, }, serviceUrl diff --git a/src/modules/firestore/index.js b/src/modules/firestore/index.js index 7d336159..efbdc5c4 100644 --- a/src/modules/firestore/index.js +++ b/src/modules/firestore/index.js @@ -69,8 +69,8 @@ export default class Firestore extends ModuleBase { super(app, { events: NATIVE_EVENTS, moduleName: MODULE_NAME, - multiApp: true, - hasShards: false, + hasMultiAppSupport: true, + hasCustomUrlSupport: false, namespace: NAMESPACE, }); diff --git a/src/modules/iid/index.js b/src/modules/iid/index.js index 773fb033..f6ce3a85 100644 --- a/src/modules/iid/index.js +++ b/src/modules/iid/index.js @@ -13,9 +13,9 @@ export const MODULE_NAME = 'RNFirebaseInstanceId'; export default class InstanceId extends ModuleBase { constructor(app: App) { super(app, { - hasShards: false, + hasCustomUrlSupport: false, moduleName: MODULE_NAME, - multiApp: false, + hasMultiAppSupport: false, namespace: NAMESPACE, }); } diff --git a/src/modules/invites/index.js b/src/modules/invites/index.js index 31f81df9..d253762d 100644 --- a/src/modules/invites/index.js +++ b/src/modules/invites/index.js @@ -24,9 +24,9 @@ export default class Invites extends ModuleBase { constructor(app: App) { super(app, { events: NATIVE_EVENTS, - hasShards: false, + hasCustomUrlSupport: false, moduleName: MODULE_NAME, - multiApp: false, + hasMultiAppSupport: false, namespace: NAMESPACE, }); diff --git a/src/modules/links/index.js b/src/modules/links/index.js index 5fca4884..cfbb55f5 100644 --- a/src/modules/links/index.js +++ b/src/modules/links/index.js @@ -24,8 +24,8 @@ export default class Links extends ModuleBase { super(app, { events: NATIVE_EVENTS, moduleName: MODULE_NAME, - multiApp: false, - hasShards: false, + hasMultiAppSupport: false, + hasCustomUrlSupport: false, namespace: NAMESPACE, }); diff --git a/src/modules/messaging/index.js b/src/modules/messaging/index.js index 52aad936..847ed664 100644 --- a/src/modules/messaging/index.js +++ b/src/modules/messaging/index.js @@ -42,8 +42,8 @@ export default class Messaging extends ModuleBase { super(app, { events: NATIVE_EVENTS, moduleName: MODULE_NAME, - multiApp: false, - hasShards: false, + hasMultiAppSupport: false, + hasCustomUrlSupport: false, namespace: NAMESPACE, }); diff --git a/src/modules/notifications/index.js b/src/modules/notifications/index.js index b42d3d65..ec0ae608 100644 --- a/src/modules/notifications/index.js +++ b/src/modules/notifications/index.js @@ -77,9 +77,9 @@ export default class Notifications extends ModuleBase { constructor(app: App) { super(app, { events: NATIVE_EVENTS, - hasShards: false, + hasCustomUrlSupport: false, moduleName: MODULE_NAME, - multiApp: false, + hasMultiAppSupport: false, namespace: NAMESPACE, }); this._android = new AndroidNotifications(this); diff --git a/src/modules/perf/index.js b/src/modules/perf/index.js index a7a25ad7..bb3dc2a4 100644 --- a/src/modules/perf/index.js +++ b/src/modules/perf/index.js @@ -39,8 +39,8 @@ export default class PerformanceMonitoring extends ModuleBase { constructor(app: App) { super(app, { moduleName: MODULE_NAME, - multiApp: false, - hasShards: false, + hasMultiAppSupport: false, + hasCustomUrlSupport: false, namespace: NAMESPACE, }); } diff --git a/src/modules/storage/index.js b/src/modules/storage/index.js index 468ed029..08216090 100644 --- a/src/modules/storage/index.js +++ b/src/modules/storage/index.js @@ -30,8 +30,8 @@ export default class Storage extends ModuleBase { super(app, { events: NATIVE_EVENTS, moduleName: MODULE_NAME, - multiApp: true, - hasShards: false, + hasMultiAppSupport: true, + hasCustomUrlSupport: false, namespace: NAMESPACE, }); diff --git a/src/modules/utils/index.js b/src/modules/utils/index.js index fdb77ae2..2e6f2921 100644 --- a/src/modules/utils/index.js +++ b/src/modules/utils/index.js @@ -22,8 +22,8 @@ export default class RNFirebaseUtils extends ModuleBase { constructor(app: App) { super(app, { moduleName: MODULE_NAME, - multiApp: false, - hasShards: false, + hasMultiAppSupport: false, + hasCustomUrlSupport: false, namespace: NAMESPACE, }); } diff --git a/src/types/index.js b/src/types/index.js index 758f4a15..e2b233ce 100644 --- a/src/types/index.js +++ b/src/types/index.js @@ -49,8 +49,9 @@ export type FirebaseModule = $Subtype; export type FirebaseModuleConfig = { events?: string[], moduleName: FirebaseModuleName, - multiApp: boolean, - hasShards: boolean, + hasMultiAppSupport: boolean, + hasCustomUrlSupport: boolean, + hasRegionsSupport: boolean, namespace: FirebaseNamespace, }; diff --git a/src/utils/ModuleBase.js b/src/utils/ModuleBase.js index 46a06f69..fd93935f 100644 --- a/src/utils/ModuleBase.js +++ b/src/utils/ModuleBase.js @@ -10,7 +10,7 @@ import type { FirebaseModuleConfig, FirebaseNamespace } from '../types'; export default class ModuleBase { _app: App; - _serviceUrl: ?string; + _customUrlOrRegion: ?string; namespace: FirebaseNamespace; @@ -18,21 +18,29 @@ export default class ModuleBase { * * @param app * @param config + * @param customUrlOrRegion */ - constructor(app: App, config: FirebaseModuleConfig, serviceUrl: ?string) { + constructor( + app: App, + config: FirebaseModuleConfig, + customUrlOrRegion: ?string + ) { if (!config.moduleName) { throw new Error('Missing module name'); } + if (!config.namespace) { throw new Error('Missing namespace'); } + const { moduleName } = config; this._app = app; - this._serviceUrl = serviceUrl; + this._customUrlOrRegion = customUrlOrRegion; this.namespace = config.namespace; // check if native module exists as all native - initialiseNativeModule(this, config, serviceUrl); + initialiseNativeModule(this, config, customUrlOrRegion); + initialiseLogger( this, `${app.name}:${moduleName.replace('RNFirebase', '')}` diff --git a/src/utils/apps.js b/src/utils/apps.js index d219f7eb..3326d1fa 100644 --- a/src/utils/apps.js +++ b/src/utils/apps.js @@ -49,38 +49,50 @@ export default { namespace: FirebaseNamespace, InstanceClass: Class ): () => FirebaseModule { - return (serviceUrl: ?string = null): M => { - if (serviceUrl && namespace !== 'database') { + return (customUrlOrRegion: ?string = null): M => { + if ( + customUrlOrRegion && + (namespace !== 'database' || namespace !== 'functions') + ) { throw new Error( - INTERNALS.STRINGS.ERROR_INIT_SERVICE_URL_UNSUPPORTED(namespace) + INTERNALS.STRINGS.ERROR_INIT_SERVICE_URL_OR_REGION_UNSUPPORTED( + namespace + ) ); } - const appOrShardName = serviceUrl || app.name; - if (!APP_MODULES[appOrShardName]) { - APP_MODULES[appOrShardName] = {}; + const appInstanceIdentifier = `${app.name}${customUrlOrRegion || ''}`; + + if (!APP_MODULES[appInstanceIdentifier]) { + APP_MODULES[appInstanceIdentifier] = {}; } - if ( - isAndroid && - namespace !== 'utils' && - !INTERNALS.FLAGS.checkedPlayServices - ) { - INTERNALS.FLAGS.checkedPlayServices = true; - app.utils().checkPlayServicesAvailability(); - } - - if (!APP_MODULES[appOrShardName][namespace]) { - APP_MODULES[appOrShardName][namespace] = new InstanceClass( - serviceUrl || app, + if (!APP_MODULES[appInstanceIdentifier][namespace]) { + APP_MODULES[appInstanceIdentifier][namespace] = new InstanceClass( + customUrlOrRegion || app, app.options ); + + // only check once on new app namespace instance + if ( + isAndroid && + namespace !== 'utils' && + !INTERNALS.FLAGS.checkedPlayServices + ) { + INTERNALS.FLAGS.checkedPlayServices = true; + app.utils().checkPlayServicesAvailability(); + } } - return APP_MODULES[appOrShardName][namespace]; + return APP_MODULES[appInstanceIdentifier][namespace]; }; }, + /** + * + * @param name + * @returns {*} + */ deleteApp(name: string): Promise { const app = APPS[name]; if (!app) return Promise.resolve(true); @@ -173,24 +185,31 @@ export default { statics: S, moduleName: FirebaseModuleName ): FirebaseModuleAndStatics { - const getModule = (appOrUrl?: App | string): FirebaseModule => { - let _app = appOrUrl; - let _serviceUrl: ?string = null; - if (typeof appOrUrl === 'string' && namespace === 'database') { + const getModule = (appOrUrlOrRegion?: App | string): FirebaseModule => { + let _app = appOrUrlOrRegion; + let _customUrlOrRegion: ?string = null; + + if (typeof appOrUrlOrRegion === 'string' && namespace === 'database') { _app = null; - _serviceUrl = appOrUrl; + _customUrlOrRegion = appOrUrlOrRegion; + } + + if (typeof appOrUrlOrRegion === 'string' && namespace === 'functions') { + _app = null; + _customUrlOrRegion = appOrUrlOrRegion; } // throw an error if it's not a valid app instance - if (_app && !(_app instanceof App)) + if (_app && !(_app instanceof App)) { throw new Error(INTERNALS.STRINGS.ERROR_NOT_APP(namespace)); - else if (!_app) + } else if (!_app) { // default to the 'DEFAULT' app if no arg provided - will throw an error // if default app not initialized _app = this.app(DEFAULT_APP_NAME); + } // $FlowExpectedError: Flow doesn't support indexable signatures on classes: https://github.com/facebook/flow/issues/1323 const module = _app[namespace]; - return module(_serviceUrl); + return module(_customUrlOrRegion); }; return Object.assign(getModule, statics, { diff --git a/src/utils/events.js b/src/utils/events.js index 1d53798e..7b99ed77 100644 --- a/src/utils/events.js +++ b/src/utils/events.js @@ -23,9 +23,11 @@ const getNativeEmitter = ( ): NativeEventEmitter => { const name = `${module.app.name}-${moduleName}`; const nativeModule = NativeModules[moduleName]; + if (!NATIVE_EMITTERS[name]) { NATIVE_EMITTERS[name] = new NativeEventEmitter(nativeModule); } + return NATIVE_EMITTERS[name]; }; @@ -35,6 +37,7 @@ const getNativeEmitter = ( * so we use a single event send it to js and js then internally can prefix it * and distribute dynamically. * + * @param moduleName * @param module * @param eventName * @private @@ -65,6 +68,7 @@ export const initialiseNativeModuleEventEmitter = ( config: FirebaseModuleConfig ): void => { const { events, moduleName } = config; + if (events && events.length) { for (let i = 0, len = events.length; i < len; i++) { subscribeToNativeModuleEvents(moduleName, module, events[i]); diff --git a/src/utils/internals.js b/src/utils/internals.js index 419bd5f1..f63395de 100644 --- a/src/utils/internals.js +++ b/src/utils/internals.js @@ -100,8 +100,8 @@ export default { /** * @return {string} */ - ERROR_INIT_SERVICE_URL_UNSUPPORTED(namespace: string) { - return `${namespace} does not support URL as a param, please pass in an app.`; + ERROR_INIT_SERVICE_URL_OR_REGION_UNSUPPORTED(namespace: string) { + return `${namespace} does not support a URL or region as a param, please pass in an app.`; }, /** diff --git a/src/utils/native.js b/src/utils/native.js index 1b8ddd66..95cdd982 100644 --- a/src/utils/native.js +++ b/src/utils/native.js @@ -32,7 +32,7 @@ const nativeWithArgs = ( }; const nativeModuleKey = (module: ModuleBase): string => - `${module._serviceUrl || module.app.name}:${module.namespace}`; + `${module._customUrlOrRegion || module.app.name}:${module.namespace}`; export const getNativeModule = (module: ModuleBase): Object => NATIVE_MODULES[nativeModuleKey(module)]; @@ -40,9 +40,9 @@ export const getNativeModule = (module: ModuleBase): Object => export const initialiseNativeModule = ( module: ModuleBase, config: FirebaseModuleConfig, - serviceUrl: ?string + customUrlOrRegion: ?string ): Object => { - const { moduleName, multiApp, hasShards, namespace } = config; + const { moduleName, hasMultiAppSupport, hasCustomUrlSupport, hasRegionsSupport, namespace } = config; const nativeModule = NativeModules[moduleName]; const key = nativeModuleKey(module); @@ -55,11 +55,13 @@ export const initialiseNativeModule = ( // used by the modules that extend ModuleBase // to access their native module counterpart const argToPrepend = []; - if (multiApp) { + + if (hasMultiAppSupport) { argToPrepend.push(module.app.name); } - if (hasShards) { - argToPrepend.push(serviceUrl); + + if (hasCustomUrlSupport || hasRegionsSupport) { + argToPrepend.push(customUrlOrRegion); } if (argToPrepend.length) {