mirror of
https://github.com/zhigang1992/react-native-firebase.git
synced 2026-04-23 12:06:47 +08:00
Implement multiple database shard support
This commit is contained in:
committed by
Akshet Pandey
parent
213f03737b
commit
cc8799b465
@@ -9,6 +9,7 @@ import type { FirebaseModuleConfig, FirebaseNamespace } from '../types';
|
||||
|
||||
export default class ModuleBase {
|
||||
_app: App;
|
||||
_serviceUrl: ?string;
|
||||
namespace: FirebaseNamespace;
|
||||
|
||||
/**
|
||||
@@ -16,7 +17,7 @@ export default class ModuleBase {
|
||||
* @param app
|
||||
* @param config
|
||||
*/
|
||||
constructor(app: App, config: FirebaseModuleConfig) {
|
||||
constructor(app: App, config: FirebaseModuleConfig, serviceUrl: ?string) {
|
||||
if (!config.moduleName) {
|
||||
throw new Error('Missing module name');
|
||||
}
|
||||
@@ -25,10 +26,11 @@ export default class ModuleBase {
|
||||
}
|
||||
const { moduleName } = config;
|
||||
this._app = app;
|
||||
this._serviceUrl = serviceUrl;
|
||||
this.namespace = config.namespace;
|
||||
|
||||
// check if native module exists as all native
|
||||
initialiseNativeModule(this, config);
|
||||
initialiseNativeModule(this, config, serviceUrl);
|
||||
initialiseLogger(
|
||||
this,
|
||||
`${app.name}:${moduleName.replace('RNFirebase', '')}`
|
||||
|
||||
@@ -49,9 +49,16 @@ export default {
|
||||
namespace: FirebaseNamespace,
|
||||
InstanceClass: Class<M>
|
||||
): () => FirebaseModule {
|
||||
return (): M => {
|
||||
if (!APP_MODULES[app._name]) {
|
||||
APP_MODULES[app._name] = {};
|
||||
return (serviceUrl: ?string = null): M => {
|
||||
if (serviceUrl && namespace !== 'database') {
|
||||
throw new Error(
|
||||
INTERNALS.STRINGS.ERROR_INIT_SERVICE_URL_UNSUPPORTED(namespace)
|
||||
);
|
||||
}
|
||||
|
||||
const appOrShardName = serviceUrl || app.name;
|
||||
if (!APP_MODULES[appOrShardName]) {
|
||||
APP_MODULES[appOrShardName] = {};
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -63,11 +70,14 @@ export default {
|
||||
app.utils().checkPlayServicesAvailability();
|
||||
}
|
||||
|
||||
if (!APP_MODULES[app._name][namespace]) {
|
||||
APP_MODULES[app._name][namespace] = new InstanceClass(app, app.options);
|
||||
if (!APP_MODULES[appOrShardName][namespace]) {
|
||||
APP_MODULES[appOrShardName][namespace] = new InstanceClass(
|
||||
serviceUrl || app,
|
||||
app.options
|
||||
);
|
||||
}
|
||||
|
||||
return APP_MODULES[app._name][namespace];
|
||||
return APP_MODULES[appOrShardName][namespace];
|
||||
};
|
||||
},
|
||||
|
||||
@@ -163,8 +173,13 @@ export default {
|
||||
statics: S,
|
||||
moduleName: FirebaseModuleName
|
||||
): FirebaseModuleAndStatics<M, S> {
|
||||
const getModule = (app?: App): FirebaseModule => {
|
||||
let _app = app;
|
||||
const getModule = (appOrUrl?: App | string): FirebaseModule => {
|
||||
let _app = appOrUrl;
|
||||
let _serviceUrl: ?string = null;
|
||||
if (typeof appOrUrl === 'string' && namespace === 'database') {
|
||||
_app = null;
|
||||
_serviceUrl = appOrUrl;
|
||||
}
|
||||
|
||||
// throw an error if it's not a valid app instance
|
||||
if (_app && !(_app instanceof App))
|
||||
@@ -178,7 +193,7 @@ export default {
|
||||
}
|
||||
// $FlowExpectedError: Flow doesn't support indexable signatures on classes: https://github.com/facebook/flow/issues/1323
|
||||
const module = _app[namespace];
|
||||
return module();
|
||||
return module(_serviceUrl);
|
||||
};
|
||||
|
||||
return Object.assign(getModule, statics, {
|
||||
|
||||
@@ -98,6 +98,13 @@ export default {
|
||||
ERROR_INIT_STRING_NAME:
|
||||
'Firebase.initializeApp(options, name <-- requires a valid string value.',
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
ERROR_INIT_SERVICE_URL_UNSUPPORTED(namespace: string) {
|
||||
return `${namespace} does not support URL as a param, please pass in an app.`;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
|
||||
@@ -11,37 +11,40 @@ import type { FirebaseModuleConfig } from '../types';
|
||||
const NATIVE_MODULES: { [string]: Object } = {};
|
||||
|
||||
/**
|
||||
* Prepends appName arg to all native method calls
|
||||
* @param appName
|
||||
* Prepends all arguments in prependArgs to all native method calls
|
||||
* @param NativeModule
|
||||
* @param argToPrepend
|
||||
*/
|
||||
const nativeWithApp = (appName: string, NativeModule: Object): Object => {
|
||||
const nativeWithArgs = (
|
||||
NativeModule: Object,
|
||||
argToPrepend: Array<mixed>
|
||||
): Object => {
|
||||
const native = {};
|
||||
const methods = Object.keys(NativeModule);
|
||||
|
||||
for (let i = 0, len = methods.length; i < len; i++) {
|
||||
const method = methods[i];
|
||||
native[method] = (...args) => NativeModule[method](...[appName, ...args]);
|
||||
native[method] = (...args) =>
|
||||
NativeModule[method](...[...argToPrepend, ...args]);
|
||||
}
|
||||
|
||||
return native;
|
||||
};
|
||||
|
||||
const getModuleKey = (module: ModuleBase): string =>
|
||||
`${module.app.name}:${module.namespace}`;
|
||||
const nativeModuleKey = (module: ModuleBase): string =>
|
||||
`${module._serviceUrl || module.app.name}:${module.namespace}`;
|
||||
|
||||
export const getNativeModule = (module: ModuleBase): Object => {
|
||||
const key = getModuleKey(module);
|
||||
return NATIVE_MODULES[key];
|
||||
};
|
||||
export const getNativeModule = (module: ModuleBase): Object =>
|
||||
NATIVE_MODULES[nativeModuleKey(module)];
|
||||
|
||||
export const initialiseNativeModule = (
|
||||
module: ModuleBase,
|
||||
config: FirebaseModuleConfig
|
||||
config: FirebaseModuleConfig,
|
||||
serviceUrl: ?string
|
||||
): Object => {
|
||||
const { moduleName, multiApp, namespace } = config;
|
||||
const { moduleName, multiApp, hasShards, namespace } = config;
|
||||
const nativeModule = NativeModules[moduleName];
|
||||
const key = getModuleKey(module);
|
||||
const key = nativeModuleKey(module);
|
||||
|
||||
if (!nativeModule && namespace !== 'utils') {
|
||||
throw new Error(
|
||||
@@ -51,8 +54,16 @@ export const initialiseNativeModule = (
|
||||
|
||||
// used by the modules that extend ModuleBase
|
||||
// to access their native module counterpart
|
||||
const argToPrepend = [];
|
||||
if (multiApp) {
|
||||
NATIVE_MODULES[key] = nativeWithApp(module.app.name, nativeModule);
|
||||
argToPrepend.push(module.app.name);
|
||||
}
|
||||
if (hasShards) {
|
||||
argToPrepend.push(serviceUrl);
|
||||
}
|
||||
|
||||
if (argToPrepend.length) {
|
||||
NATIVE_MODULES[key] = nativeWithArgs(nativeModule, argToPrepend);
|
||||
} else {
|
||||
NATIVE_MODULES[key] = nativeModule;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user