more work on multiple app initialization

This commit is contained in:
Salakar
2017-06-30 17:23:32 +01:00
parent 80ae8425ce
commit ec22e510bc
25 changed files with 493 additions and 455 deletions

View File

@@ -2,45 +2,38 @@
* @flow
* Database representation wrapper
*/
import { NativeModules, NativeEventEmitter } from 'react-native';
import { NativeModules } from 'react-native';
import { Base } from './../base';
import ModuleBase from './../../utils/ModuleBase';
import Snapshot from './snapshot';
import Reference from './reference';
import TransactionHandler from './transaction';
import { promisify, nativeSDKMissing } from './../../utils';
const FirebaseDatabase = NativeModules.RNFirebaseDatabase;
const FirebaseDatabaseEvt = FirebaseDatabase && new NativeEventEmitter(FirebaseDatabase);
import { promisify } from './../../utils';
/**
* @class Database
*/
export default class Database extends Base {
constructor(firebase: Object, options: Object = {}) {
super(firebase, options);
if (!FirebaseDatabase) {
return nativeSDKMissing('database');
}
// TODO refactor native and js - legacy code here using old fb methods
export default class Database extends ModuleBase {
constructor(firebaseApp: Object, options: Object = {}) {
super(firebaseApp, options, 'Database', true);
this.references = {};
this.serverTimeOffset = 0;
this.persistenceEnabled = false;
this.namespace = 'firebase:database';
this.transaction = new TransactionHandler(firebase, this, FirebaseDatabaseEvt);
this.transaction = new TransactionHandler(this);
if (firebase.options.persistence === true) {
if (options.persistence === true) {
this._setPersistence(true);
}
this.successListener = FirebaseDatabaseEvt.addListener(
this.successListener = this._eventEmitter.addListener(
'database_event',
event => this._handleDatabaseEvent(event)
event => this._handleDatabaseEvent(event),
);
this.errorListener = FirebaseDatabaseEvt.addListener(
this.errorListener = this._eventEmitter.addListener(
'database_error',
err => this._handleDatabaseError(err)
err => this._handleDatabaseError(err),
);
this.offsetRef = this.ref('.info/serverTimeOffset');
@@ -63,34 +56,26 @@ export default class Database extends Base {
/**
*
* @param path
* @param modifiersString
* @param modifiers
* @param eventName
* @param cb
* @param errorCb
* @returns {*}
* @param ref
* @param listener
*/
on(ref: Reference, listener: DatabaseListener) {
const { refId, path, query } = ref;
const { listenerId, eventName } = listener;
this.log.debug('on() : ', ref.refId, listenerId, eventName);
this.references[refId] = ref;
return promisify('on', FirebaseDatabase)(refId, path, query.getModifiers(), listenerId, eventName);
return promisify('on', this._native)(refId, path, query.getModifiers(), listenerId, eventName);
}
/**
*
* @param path
* @param modifiersString
* @param eventName
* @param origCB
* @returns {*}
* @param refId
* @param listeners
* @param remainingListenersCount
*/
off(refId: number,
// $FlowFixMe
listeners: Array<DatabaseListener>,
remainingListenersCount: number) {
off(refId: number, listeners: Array<DatabaseListener>, remainingListenersCount: number) {
this.log.debug('off() : ', refId, listeners);
// Delete the reference if there are no more listeners
@@ -98,7 +83,7 @@ export default class Database extends Base {
if (listeners.length === 0) return Promise.resolve();
return promisify('off', FirebaseDatabase)(refId, listeners.map(listener => ({
return promisify('off', this._native)(refId, listeners.map(listener => ({
listenerId: listener.listenerId,
eventName: listener.eventName,
})));
@@ -118,11 +103,11 @@ export default class Database extends Base {
}
goOnline() {
FirebaseDatabase.goOnline();
this._native.goOnline();
}
goOffline() {
FirebaseDatabase.goOffline();
this._native.goOffline();
}
/**
@@ -142,7 +127,7 @@ export default class Database extends Base {
if (this.persistenceEnabled !== enable) {
this.persistenceEnabled = enable;
this.log.debug(`${enable ? 'Enabling' : 'Disabling'} persistence.`);
return promisify('enablePersistence', FirebaseDatabase)(enable);
return promisify('enablePersistence', this._native)(enable);
}
return Promise.reject({ status: 'Already enabled' });
@@ -161,7 +146,7 @@ export default class Database extends Base {
const cb = this.references[refId].refListeners[listenerId].successCallback;
cb(new Snapshot(this.references[refId], snapshot), previousChildName);
} else {
FirebaseDatabase.off(refId, [{ listenerId, eventName }], () => {
this._native.off(refId, [{ listenerId, eventName }], () => {
this.log.debug('_handleDatabaseEvent: No JS listener registered, removed native listener', refId, listenerId, eventName);
});
}
@@ -211,7 +196,7 @@ export default class Database extends Base {
}
export const statics = {
ServerValue: FirebaseDatabase ? {
TIMESTAMP: FirebaseDatabase.serverValueTimestamp || { '.sv': 'timestamp' },
ServerValue: NativeModules.FirebaseDatabase ? {
TIMESTAMP: NativeModules.FirebaseDatabase.serverValueTimestamp || { '.sv': 'timestamp' },
} : {},
};

View File

@@ -2,7 +2,7 @@
* @flow
*/
import { ReferenceBase } from './../base';
import ReferenceBase from './../../utils/ModuleBase';
import Reference from './reference.js';
/**

View File

@@ -1,15 +1,12 @@
/**
* @flow
*/
import { NativeModules } from 'react-native';
import Query from './query.js';
import Snapshot from './snapshot';
import Disconnect from './disconnect';
import { ReferenceBase } from './../base';
import ReferenceBase from './../../utils/ReferenceBase';
import { promisify, isFunction, isObject, tryJSONParse, tryJSONStringify, generatePushID } from './../../utils';
const FirebaseDatabase = NativeModules.RNFirebaseDatabase;
// Unique Reference ID for native events
let refId = 1;
@@ -57,10 +54,11 @@ export default class Reference extends ReferenceBase {
refId: number;
refListeners: { [listenerId: number]: DatabaseListener };
database: FirebaseDatabase;
database: Object;
query: Query;
constructor(database: FirebaseDatabase, path: string, existingModifiers?: Array<DatabaseModifier>) {
// todo logger missing as reference base no longer extends module base
constructor(database: Object, path: string, existingModifiers?: Array<DatabaseModifier>) {
super(path);
this.refId = refId++;
this.refListeners = {};
@@ -77,7 +75,7 @@ export default class Reference extends ReferenceBase {
*/
keepSynced(bool: boolean) {
const path = this.path;
return promisify('keepSynced', FirebaseDatabase)(path, bool);
return promisify('keepSynced', this.database._native)(path, bool);
}
/**
@@ -88,7 +86,7 @@ export default class Reference extends ReferenceBase {
set(value: any) {
const path = this.path;
const _value = this._serializeAnyType(value);
return promisify('set', FirebaseDatabase)(path, _value);
return promisify('set', this.database._native)(path, _value);
}
/**
@@ -99,7 +97,7 @@ export default class Reference extends ReferenceBase {
update(val: Object) {
const path = this.path;
const value = this._serializeObject(val);
return promisify('update', FirebaseDatabase)(path, value);
return promisify('update', this.database._native)(path, value);
}
/**
@@ -107,7 +105,7 @@ export default class Reference extends ReferenceBase {
* @returns {*}
*/
remove() {
return promisify('remove', FirebaseDatabase)(this.path);
return promisify('remove', this.database._native)(this.path);
}
/**
@@ -123,7 +121,7 @@ export default class Reference extends ReferenceBase {
const path = this.path;
const _value = this._serializeAnyType(value);
return promisify('push', FirebaseDatabase)(path, _value)
return promisify('push', this.database._native)(path, _value)
.then(({ ref }) => {
const newRef = new Reference(this.database, ref);
if (isFunction(onComplete)) return onComplete(null, newRef);
@@ -244,31 +242,26 @@ export default class Reference extends ReferenceBase {
if (arguments.length > 2 && !failureCallbackOrContext) throw new Error('Query.on failed: third argument must either be a cancel callback or a context object.');
this.log.debug('adding reference.on', this.refId, eventType);
let _failureCallback;
let _context;
if (context) {
_context = context;
_failureCallback = failureCallbackOrContext;
} else if (isFunction(failureCallbackOrContext)) {
_failureCallback = failureCallbackOrContext;
} else {
if (isFunction(failureCallbackOrContext)) {
_failureCallback = failureCallbackOrContext;
} else {
_context = failureCallbackOrContext;
}
_context = failureCallbackOrContext;
}
if (_failureCallback) {
_failureCallback = (error) => {
if (error.message.startsWith('FirebaseError: permission_denied')) {
error.message = `permission_denied at /${this.path}: Client doesn\'t have permission to access the desired data.`
error.message = `permission_denied at /${this.path}: Client doesn't have permission to access the desired data.`
}
failureCallbackOrContext(error);
}
};
}
let _successCallback;
@@ -300,7 +293,7 @@ export default class Reference extends ReferenceBase {
* @returns {Promise.<TResult>}
*/
once(eventName: string = 'value', successCallback: (snapshot: Object) => void, failureCallback: (error: FirebaseError) => void) {
return promisify('once', FirebaseDatabase)(this.refId, this.path, this.query.getModifiers(), eventName)
return promisify('once', this.database._native)(this.refId, this.path, this.query.getModifiers(), eventName)
.then(({ snapshot }) => new Snapshot(this, snapshot))
.then((snapshot) => {
if (isFunction(successCallback)) successCallback(snapshot);
@@ -375,14 +368,10 @@ export default class Reference extends ReferenceBase {
* @param onComplete
* @param applyLocally
*/
transaction(
transactionUpdate: Function,
onComplete: (error: ?Error, committed: boolean, snapshot: ?Snapshot) => *,
applyLocally: boolean = false
) {
transaction(transactionUpdate: Function, onComplete: (error: ?Error, committed: boolean, snapshot: ?Snapshot) => *, applyLocally: boolean = false) {
if (!isFunction(transactionUpdate)) {
return Promise.reject(
new Error('Missing transactionUpdate function argument.')
new Error('Missing transactionUpdate function argument.'),
);
}
@@ -588,7 +577,7 @@ export default class Reference extends ReferenceBase {
*
* {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#parent}
*/
get parent(): Reference|null {
get parent(): Reference | null {
if (this.path === '/') return null;
return new Reference(this.database, this.path.substring(0, this.path.lastIndexOf('/')));
}

View File

@@ -2,26 +2,19 @@
* @flow
* Database representation wrapper
*/
import { NativeModules } from 'react-native';
import { Base } from './../base';
import { generatePushID } from './../../utils';
const FirebaseDatabase = NativeModules.RNFirebaseDatabase;
/**
* @class Database
*/
export default class TransactionHandler extends Base {
constructor(firebase: Object, database: Object, FirebaseDatabaseEvt: Object) {
super(firebase, {});
this.transactions = {};
this.database = database;
this.namespace = 'firebase:database:transaction';
this.transactionListener = FirebaseDatabaseEvt.addListener(
export default class TransactionHandler {
constructor(database: Object) {
this._transactions = {};
this._database = database;
this._transactionListener = this._database._eventEmitter.addListener(
'database_transaction_event',
event => this._handleTransactionEvent(event)
event => this._handleTransactionEvent(event),
);
}
@@ -40,7 +33,7 @@ export default class TransactionHandler extends Base {
) {
const id = this._generateTransactionId();
this.transactions[id] = {
this._transactions[id] = {
id,
reference,
transactionUpdater,
@@ -50,7 +43,7 @@ export default class TransactionHandler extends Base {
started: true,
};
FirebaseDatabase.startTransaction(reference.path, id, applyLocally);
this._database._native.startTransaction(reference.path, id, applyLocally);
}
/**
@@ -63,7 +56,7 @@ export default class TransactionHandler extends Base {
* @private
*/
_generateTransactionId(): string {
return generatePushID(this.database.serverTimeOffset);
return generatePushID(this._database.serverTimeOffset);
}
/**
@@ -96,7 +89,7 @@ export default class TransactionHandler extends Base {
const { id, value } = event;
try {
const transaction = this.transactions[id];
const transaction = this._transactions[id];
// todo handle when transaction no longer exists on js side?
newValue = transaction.transactionUpdater(value);
} finally {
@@ -106,7 +99,7 @@ export default class TransactionHandler extends Base {
abort = true;
}
FirebaseDatabase.tryCommitTransaction(id, { value: newValue, abort });
this._database._native.tryCommitTransaction(id, { value: newValue, abort });
}
}
@@ -116,14 +109,14 @@ export default class TransactionHandler extends Base {
* @private
*/
_handleError(event: Object = {}) {
const transaction = this.transactions[event.id];
const transaction = this._transactions[event.id];
if (transaction && !transaction.completed) {
transaction.completed = true;
try {
transaction.onComplete(new Error(event.message, event.code), null);
} finally {
setImmediate(() => {
delete this.transactions[event.id];
delete this._transactions[event.id];
});
}
}
@@ -135,14 +128,14 @@ export default class TransactionHandler extends Base {
* @private
*/
_handleComplete(event: Object = {}) {
const transaction = this.transactions[event.id];
const transaction = this._transactions[event.id];
if (transaction && !transaction.completed) {
transaction.completed = true;
try {
transaction.onComplete(null, event.committed, Object.assign({}, event.snapshot));
} finally {
setImmediate(() => {
delete this.transactions[event.id];
delete this._transactions[event.id];
});
}
}