2017-03-02 11:40:08 +00:00
|
|
|
/**
|
|
|
|
* @flow
|
|
|
|
* Database representation wrapper
|
|
|
|
*/
|
2017-06-30 16:23:32 +00:00
|
|
|
import { NativeModules } from 'react-native';
|
2017-03-02 11:40:08 +00:00
|
|
|
|
2017-03-24 22:53:56 +00:00
|
|
|
import Reference from './reference';
|
2017-08-14 10:05:49 +00:00
|
|
|
import Snapshot from './snapshot';
|
2017-03-24 22:53:56 +00:00
|
|
|
import TransactionHandler from './transaction';
|
2017-07-30 06:34:41 +00:00
|
|
|
import ModuleBase from './../../utils/ModuleBase';
|
2017-08-14 17:41:50 +00:00
|
|
|
import { nativeToJSError } from './../../utils';
|
2017-03-02 11:40:08 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @class Database
|
|
|
|
*/
|
2017-06-30 16:23:32 +00:00
|
|
|
export default class Database extends ModuleBase {
|
|
|
|
constructor(firebaseApp: Object, options: Object = {}) {
|
|
|
|
super(firebaseApp, options, 'Database', true);
|
2017-08-14 10:05:49 +00:00
|
|
|
this._references = {};
|
2017-08-02 09:38:30 +00:00
|
|
|
this._serverTimeOffset = 0;
|
2017-07-30 06:34:41 +00:00
|
|
|
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
|
|
|
|
2017-07-30 06:34:41 +00:00
|
|
|
// todo serverTimeOffset event/listener - make ref natively and switch to events
|
|
|
|
// todo use nativeToJSError for on/off error events
|
2017-08-14 10:05:49 +00:00
|
|
|
this.addListener(
|
|
|
|
this._getAppEventName('database_cancel_event'),
|
|
|
|
this._handleCancelEvent.bind(this),
|
|
|
|
);
|
|
|
|
|
|
|
|
this.addListener(
|
|
|
|
this._getAppEventName('database_on_event'),
|
|
|
|
this._handleOnEvent.bind(this),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2017-08-14 17:41:50 +00:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2017-08-14 10:05:49 +00:00
|
|
|
_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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-14 17:41:50 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Routes native database query listener cancellation events to their js counterparts.
|
|
|
|
*
|
|
|
|
* @param event
|
|
|
|
* @private
|
|
|
|
*/
|
2017-08-14 10:05:49 +00:00
|
|
|
_handleCancelEvent(event) {
|
2017-08-14 17:41:50 +00:00
|
|
|
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() {
|
2017-06-30 16:23:32 +00:00
|
|
|
this._native.goOnline();
|
2017-03-02 11:40:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2017-07-30 06:34:41 +00:00
|
|
|
goOffline() {
|
|
|
|
this._native.goOffline();
|
2017-03-07 16:54:04 +00:00
|
|
|
}
|
|
|
|
|
2017-03-02 11:40:08 +00:00
|
|
|
/**
|
2017-07-30 06:34:41 +00:00
|
|
|
* Returns a new firebase reference instance
|
|
|
|
* @param path
|
|
|
|
* @returns {Reference}
|
2017-03-02 11:40:08 +00:00
|
|
|
*/
|
2017-07-30 06:34:41 +00:00
|
|
|
ref(path: string) {
|
|
|
|
return new Reference(this, path);
|
2017-03-02 11:40:08 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-22 20:15:02 +00:00
|
|
|
|
|
|
|
export const statics = {
|
2017-06-30 16:23:32 +00:00
|
|
|
ServerValue: NativeModules.FirebaseDatabase ? {
|
|
|
|
TIMESTAMP: NativeModules.FirebaseDatabase.serverValueTimestamp || { '.sv': 'timestamp' },
|
2017-05-31 14:45:14 +00:00
|
|
|
} : {},
|
2017-03-22 20:15:02 +00:00
|
|
|
};
|