react-native-firebase/lib/modules/database/index.js

129 lines
3.1 KiB
JavaScript
Raw Normal View History

2017-03-02 11:40:08 +00:00
/**
* @flow
* Database representation wrapper
*/
import { NativeModules } from 'react-native';
2017-03-02 11:40:08 +00:00
import Reference from './reference';
import Snapshot from './snapshot';
import TransactionHandler from './transaction';
import ModuleBase from './../../utils/ModuleBase';
import { nativeToJSError } from './../../utils';
2017-03-02 11:40:08 +00:00
/**
* @class Database
*/
export default class Database extends ModuleBase {
constructor(firebaseApp: Object, options: Object = {}) {
super(firebaseApp, options, 'Database', true);
this._references = {};
2017-08-02 09:38:30 +00:00
this._serverTimeOffset = 0;
this._transactionHandler = new TransactionHandler(this);
2017-08-02 09:38:30 +00:00
if (this._options.persistence) {
this._native.setPersistence(this._options.persistence);
}
2017-03-02 11:40:08 +00:00
// todo serverTimeOffset event/listener - make ref natively and switch to events
// todo use nativeToJSError for on/off error events
this.addListener(
this._getAppEventName('database_cancel_event'),
this._handleCancelEvent.bind(this),
);
this.addListener(
this._getAppEventName('database_on_event'),
this._handleOnEvent.bind(this),
);
}
/**
* Routes native database 'on' events to their js equivalent counterpart.
* If there is no longer any listeners remaining for this event we internally
* call the native unsub method to prevent further events coming through.
*
* @param event
* @private
*/
_handleOnEvent(event) {
const { queryKey, body, refId } = event;
const { snapshot, previousChildName } = body;
const remainingListeners = this.listeners(queryKey);
if (!remainingListeners || !remainingListeners.length) {
this._database._native.off(
_refId,
queryKey,
);
delete this._references[refId];
} else {
const ref = this._references[refId];
if (!ref) {
this._database._native.off(
_refId,
queryKey,
);
} else {
this.emit(queryKey, new Snapshot(ref, snapshot), previousChildName);
}
}
}
/**
* Routes native database query listener cancellation events to their js counterparts.
*
* @param event
* @private
*/
_handleCancelEvent(event) {
const { queryKey, code, message, path, refId, appName } = event;
const remainingListeners = this.listeners(`${queryKey}:cancelled`);
if (remainingListeners && remainingListeners.length) {
const error = nativeToJSError(code, message, { path, queryKey, refId, appName });
this.emit(`${queryKey}:cancelled`, error);
}
2017-03-02 11:40:08 +00:00
}
2017-08-02 09:38:30 +00:00
/**
*
* @return {number}
*/
getServerTime() {
return new Date().getTime() + this._serverTimeOffset;
}
2017-03-02 11:40:08 +00:00
/**
*
*/
goOnline() {
this._native.goOnline();
2017-03-02 11:40:08 +00:00
}
/**
*
*/
goOffline() {
this._native.goOffline();
}
2017-03-02 11:40:08 +00:00
/**
* Returns a new firebase reference instance
* @param path
* @returns {Reference}
2017-03-02 11:40:08 +00:00
*/
ref(path: string) {
return new Reference(this, path);
2017-03-02 11:40:08 +00:00
}
}
export const statics = {
ServerValue: NativeModules.FirebaseDatabase ? {
TIMESTAMP: NativeModules.FirebaseDatabase.serverValueTimestamp || { '.sv': 'timestamp' },
} : {},
};