[js][internals] internals re-write to generalise `app()`/`ModuleBase` arguments - now uses `customUrlOrRegion` - meaning support for custom functions() regions, custom database() shard urls and custom storage() bucket urls internally use the same logic

This commit is contained in:
Salakar 2018-08-13 23:06:15 +01:00
parent 098edb35b5
commit 7632da1809
21 changed files with 105 additions and 71 deletions

View File

@ -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,
});

View File

@ -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,
});
}

View File

@ -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;

View File

@ -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;

View File

@ -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,
});
}

View File

@ -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

View File

@ -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,
});

View File

@ -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,
});
}

View File

@ -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,
});

View File

@ -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,
});

View File

@ -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,
});

View File

@ -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);

View File

@ -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,
});
}

View File

@ -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,
});

View File

@ -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,
});
}

View File

@ -49,8 +49,9 @@ export type FirebaseModule = $Subtype<ModuleBase>;
export type FirebaseModuleConfig = {
events?: string[],
moduleName: FirebaseModuleName,
multiApp: boolean,
hasShards: boolean,
hasMultiAppSupport: boolean,
hasCustomUrlSupport: boolean,
hasRegionsSupport: boolean,
namespace: FirebaseNamespace,
};

View File

@ -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', '')}`

View File

@ -49,38 +49,50 @@ export default {
namespace: FirebaseNamespace,
InstanceClass: Class<M>
): () => 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<boolean> {
const app = APPS[name];
if (!app) return Promise.resolve(true);
@ -173,24 +185,31 @@ export default {
statics: S,
moduleName: FirebaseModuleName
): FirebaseModuleAndStatics<M, S> {
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, {

View File

@ -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]);

View File

@ -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.`;
},
/**

View File

@ -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) {