react-native-firebase/lib/firebase.js

210 lines
5.4 KiB
JavaScript
Raw Normal View History

2017-03-02 13:10:10 +00:00
/**
* @providesModule Firebase
* @flow
*/
import { NativeModules, NativeEventEmitter } from 'react-native';
2017-03-02 13:10:10 +00:00
import { isObject, isString } from './utils';
2017-03-02 13:10:10 +00:00
import INTERNALS from './internals';
import PACKAGE from './../package.json';
import FirebaseApp from './firebase-app';
// module imports
2017-03-27 18:11:26 +00:00
import Auth, { statics as AuthStatics } from './modules/auth';
2017-07-04 12:05:19 +00:00
import RemoteConfig from './modules/config';
import Storage, { statics as StorageStatics } from './modules/storage';
import Database, { statics as DatabaseStatics } from './modules/database';
import Messaging, { statics as MessagingStatics } from './modules/messaging';
2017-03-02 13:10:10 +00:00
const FirebaseCoreModule = NativeModules.RNFirebase;
2017-03-02 13:10:10 +00:00
class FirebaseCore {
constructor() {
this._nativeEmitters = {};
this._nativeSubscriptions = {};
}
2017-04-04 16:58:20 +00:00
2017-03-02 13:10:10 +00:00
/**
* Web SDK initializeApp
2017-03-02 13:10:10 +00:00
*
* @param options
* @param name
* @return {*}
2017-03-02 13:10:10 +00:00
*/
initializeApp(options: Object = {}, name: string): FirebaseApp {
if (!isObject(options)) {
throw new Error(INTERNALS.STRINGS.ERROR_INIT_OBJECT);
}
2017-03-02 13:10:10 +00:00
// todo validate required options
2017-03-02 13:10:10 +00:00
if (name && !isString(name)) {
throw new Error(INTERNALS.STRINGS.ERROR_INIT_STRING_NAME);
2017-03-02 13:10:10 +00:00
}
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 INTERNALS.APPS[_name];
2017-03-02 13:10:10 +00:00
}
/**
* Retrieves a Firebase app instance.
*
* When called with no arguments, the default app is returned.
* When an app name is provided, the app corresponding to that name is returned.
*
2017-03-02 13:10:10 +00:00
* @param name
* @return {*}
2017-03-02 13:10:10 +00:00
*/
app(name?: string): FirebaseApp {
const _name = name ? name.toUpperCase() : INTERNALS.STRINGS.DEFAULT_APP_NAME;
const app = INTERNALS.APPS[_name];
if (!app) throw new Error(INTERNALS.STRINGS.ERROR_APP_NOT_INIT(_name));
return app;
}
2017-03-02 13:10:10 +00:00
/**
* A (read-only) array of all initialized apps.
* @return {Array}
*/
get apps(): Array<Object> {
return Object.values(INTERNALS.APPS);
}
2017-03-02 13:10:10 +00:00
/**
* The current RNFirebase SDK version.
*/
get SDK_VERSION() {
return PACKAGE.version;
}
/**
* Returns props from the android GoogleApiAvailability sdk
* @android
* @return {RNFirebase.GoogleApiAvailabilityType|{isAvailable: boolean, status: number}}
*/
get googleApiAvailabilty(): GoogleApiAvailabilityType {
return FirebaseCoreModule.googleApiAvailability || { isAvailable: true, status: 0 };
}
/*
* MODULES
*/
get auth() {
return this._appNamespaceOrStatics('auth', AuthStatics, Auth);
}
2017-03-02 13:10:10 +00:00
2017-07-04 12:05:19 +00:00
get config() {
return this._appNamespaceOrStatics('config', {}, RemoteConfig);
}
get database() {
return this._appNamespaceOrStatics('database', DatabaseStatics, Database);
2017-03-02 13:10:10 +00:00
}
get messaging() {
return this._appNamespaceOrStatics('messaging', MessagingStatics, Messaging);
2017-03-02 13:10:10 +00:00
}
get storage() {
return this._appNamespaceOrStatics('storage', StorageStatics, Storage);
}
/*
* CONFIG METHODS
*/
2017-03-02 13:10:10 +00:00
/**
* Set the global logging level for all logs.
*
* @param booleanOrDebugString
2017-03-02 13:10:10 +00:00
*/
setLogLevel(booleanOrDebugString) {
INTERNALS.OPTIONS.logLevel = booleanOrDebugString;
Log.setLevel(booleanOrDebugString);
2017-03-02 13:10:10 +00:00
}
/*
* INTERNALS
*/
2017-03-02 13:10:10 +00:00
/**
* Subscribe to a native event for js side distribution by appName
* React Native events are hard set at compile - cant do dynamic event names
* so we use a single event send it to js and js then internally can prefix it
* and distribute dynamically.
*
* @param eventName
* @param nativeEmitter
* @private
2017-03-02 13:10:10 +00:00
*/
_subscribeForDistribution(eventName, nativeEmitter) {
if (!this._nativeSubscriptions[eventName]) {
nativeEmitter.addListener(eventName, (event) => {
if (event.appName) {
// native event has an appName property - auto prefix and internally emit
INTERNALS.SharedEventEmitter.emit(`${event.appName}-${eventName}`, event);
} else {
// standard event - no need to prefix
INTERNALS.SharedEventEmitter.emit(eventName, event);
}
});
this._nativeSubscriptions[eventName] = true;
}
2017-03-02 13:10:10 +00:00
}
/**
2017-03-22 20:45:53 +00:00
*
* @param namespace
2017-03-22 20:45:53 +00:00
* @param statics
* @return {function(FirebaseApp=)}
2017-03-22 20:45:53 +00:00
* @private
*/
_appNamespaceOrStatics(namespace, statics = {}): Function {
const getNamespace = (app?: FirebaseApp) => {
let _app = app;
// throw an error if it's not a valid app instance
if (_app && !(_app instanceof FirebaseApp)) throw new Error(INTERNALS.STRINGS.ERROR_NOT_APP(namespace));
// default to the 'DEFAULT' app if no arg provided - will throw an error
// if default app not initialized
else if (!_app) _app = this.app(INTERNALS.STRINGS.DEFAULT_APP_NAME);
return INTERNALS.APPS[_app.name][namespace](_app);
2017-03-22 20:45:53 +00:00
};
2017-03-02 13:10:10 +00:00
Object.assign(getNamespace, statics);
return getNamespace;
2017-03-02 13:10:10 +00:00
}
/**
*
* @param name
* @param nativeModule
* @return {*}
* @private
*/
_getOrSetNativeEmitter(name, nativeModule) {
if (this._nativeEmitters[name]) {
return this._nativeEmitters[name];
}
return this._nativeEmitters[name] = new NativeEventEmitter(nativeModule);
}
2017-03-02 13:10:10 +00:00
}
export default new FirebaseCore();