UNPKG

@react-native-firebase/database

Version:

React Native Firebase - The Firebase Realtime Database is a cloud-hosted database. Data is stored as JSON and synchronized in realtime to every connected client. React Native Firebase provides native integration with the Android & iOS Firebase SDKs, suppo

241 lines (211 loc) 7.16 kB
/* * Copyright (c) 2016-present Invertase Limited & Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this library except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import { isAndroid, isBoolean, isNumber, isString } from '@react-native-firebase/app/lib/common'; import { createModuleNamespace, FirebaseModule, getFirebaseRoot, } from '@react-native-firebase/app/lib/internal'; import { setReactNativeModule } from '@react-native-firebase/app/lib/internal/nativeModule'; import DatabaseReference from './DatabaseReference'; import DatabaseStatics from './DatabaseStatics'; import DatabaseTransaction from './DatabaseTransaction'; import version from './version'; import fallBackModule from './web/RNFBDatabaseModule'; const namespace = 'database'; const nativeModuleName = [ 'RNFBDatabaseModule', 'RNFBDatabaseReferenceModule', 'RNFBDatabaseQueryModule', 'RNFBDatabaseOnDisconnectModule', 'RNFBDatabaseTransactionModule', ]; class FirebaseDatabaseModule extends FirebaseModule { constructor(app, config, databaseUrl) { super(app, config, databaseUrl); this._serverTimeOffset = 0; this._customUrlOrRegion = databaseUrl || this.app.options.databaseURL; this._transaction = new DatabaseTransaction(this); setTimeout(() => { this._syncServerTimeOffset(); }, 100); } /** * Keep the server time offset in sync with the server time * @private */ _syncServerTimeOffset() { this.ref('.info/serverTimeOffset').on('value', snapshot => { this._serverTimeOffset = snapshot.val(); }); } /** * * @returns {Date} * @private */ getServerTime() { return new Date(Date.now() + this._serverTimeOffset); } /** * Returns a new Reference instance from a given path. Defaults to the root reference. * @param path * @returns {DatabaseReference} */ ref(path = '/') { if (!isString(path)) { throw new Error("firebase.app().database().ref(*) 'path' must be a string value."); } if (/[#$\[\]'?]/g.test(path)) { throw new Error( `Paths must be non-empty strings and can't contain #, $, [, ], ' or ? | path: ${path}`, ); } return new DatabaseReference(this, path); } /** * Generates a Reference from a database URL. * Note domain must be the same. * Any query parameters are stripped as per the web SDK. * @param url * @returns {DatabaseReference} */ refFromURL(url) { if (!isString(url) || !url.startsWith('https://')) { throw new Error( "firebase.app().database().refFromURL(*) 'url' must be a valid database URL.", ); } if (!url.includes(this._customUrlOrRegion)) { throw new Error( `firebase.app().database().refFromURL(*) 'url' must be the same domain as the current instance (${this._customUrlOrRegion}). To use a different database domain, create a new Firebase instance.`, ); } let path = url.replace(this._customUrlOrRegion, ''); if (path.includes('?')) { path = path.slice(0, path.indexOf('?')); } return new DatabaseReference(this, path || '/'); } /** * goOnline */ goOnline() { return this.native.goOnline(); } /** * goOffline */ goOffline() { return this.native.goOffline(); } /** * * @param enabled */ setPersistenceEnabled(enabled) { if (!isBoolean(enabled)) { throw new Error( "firebase.app().database().setPersistenceEnabled(*) 'enabled' must be a boolean value.", ); } return this.native.setPersistenceEnabled(enabled); } /** * * @param enabled */ setLoggingEnabled(enabled) { if (!isBoolean(enabled)) { throw new Error( "firebase.app().database().setLoggingEnabled(*) 'enabled' must be a boolean value.", ); } return this.native.setLoggingEnabled(enabled); } /** * * @param bytes */ setPersistenceCacheSizeBytes(bytes) { if (!isNumber(bytes)) { throw new Error( "firebase.app().database().setPersistenceCacheSizeBytes(*) 'bytes' must be a number value.", ); } if (bytes < 1048576) { throw new Error( "firebase.app().database().setPersistenceCacheSizeBytes(*) 'bytes' must be greater than 1048576 bytes (1MB).", ); } if (bytes > 104857600) { throw new Error( "firebase.app().database().setPersistenceCacheSizeBytes(*) 'bytes' must be less than 104857600 bytes (100MB).", ); } return this.native.setPersistenceCacheSizeBytes(bytes); } useEmulator(host, port) { if (!host || !isString(host) || !port || !isNumber(port)) { throw new Error('firebase.database().useEmulator() takes a non-empty host and port'); } let _host = host; const androidBypassEmulatorUrlRemap = typeof this.firebaseJson.android_bypass_emulator_url_remap === 'boolean' && this.firebaseJson.android_bypass_emulator_url_remap; if (!androidBypassEmulatorUrlRemap && isAndroid && _host) { if (_host.startsWith('localhost')) { _host = _host.replace('localhost', '10.0.2.2'); // eslint-disable-next-line no-console console.log( 'Mapping database host "localhost" to "10.0.2.2" for android emulators. Use real IP on real devices. You can bypass this behaviour with "android_bypass_emulator_url_remap" flag.', ); } if (_host.startsWith('127.0.0.1')) { _host = _host.replace('127.0.0.1', '10.0.2.2'); // eslint-disable-next-line no-console console.log( 'Mapping database host "127.0.0.1" to "10.0.2.2" for android emulators. Use real IP on real devices. You can bypass this behaviour with "android_bypass_emulator_url_remap" flag.', ); } } this.native.useEmulator(_host, port); return [_host, port]; // undocumented return, just used to unit test android host remapping } } // import { SDK_VERSION } from '@react-native-firebase/database'; export const SDK_VERSION = version; // import database from '@react-native-firebase/database'; // database().X(...); export default createModuleNamespace({ statics: DatabaseStatics, version, namespace, nativeModuleName, nativeEvents: ['database_transaction_event', 'database_sync_event'], hasMultiAppSupport: true, hasCustomUrlOrRegionSupport: true, ModuleClass: FirebaseDatabaseModule, }); export * from './modular'; // import database, { firebase } from '@react-native-firebase/database'; // database().X(...); // firebase.database().X(...); export const firebase = getFirebaseRoot(); for (let i = 0; i < nativeModuleName.length; i++) { setReactNativeModule(nativeModuleName[i], fallBackModule); }