[js][database] remove, update, setWithPriority, setPriority & set now correctly support callbacks or promises

[js][database] fixed query modifier methods - were accessing incorrect query property
This commit is contained in:
Salakar 2017-08-05 21:49:28 +01:00
parent d2909be7eb
commit 53acfe3584
3 changed files with 99 additions and 35 deletions

View File

@ -5,7 +5,7 @@ import Query from './query.js';
import Snapshot from './snapshot';
import Disconnect from './disconnect';
import ReferenceBase from './../../utils/ReferenceBase';
import { isFunction, isObject, tryJSONParse, tryJSONStringify, generatePushID } from './../../utils';
import { promiseOrCallback, isFunction, isObject, tryJSONParse, tryJSONStringify, generatePushID } from './../../utils';
// Unique Reference ID for native events
let refId = 1;
@ -64,70 +64,110 @@ export default class Reference extends ReferenceBase {
this._refListeners = {};
this._database = database;
this._query = new Query(this, path, existingModifiers);
// TODO this.log.debug('Created new Reference', this._refId, this.path);
this.log = this._database.log;
this.log.debug('Created new Reference', this._refId, this.path);
}
/**
* By calling `keepSynced(true)` on a location, the data for that location will
* automatically be downloaded and kept in sync, even when no listeners are
* attached for that location. Additionally, while a location is kept synced,
* it will not be evicted from the persistent disk cache.
*
* @link https://firebase.google.com/docs/reference/android/com/google/firebase/database/Query.html#keepSynced(boolean)
* @param bool
* @returns {*}
*/
keepSynced(bool: boolean) {
return this._database._native.keepSynced(this.path, bool);
return this._database._native.keepSynced(this._refId, this.path, this._query.getModifiers(), bool);
}
/**
* Writes data to this Database location.
*
* @link https://firebase.google.com/docs/reference/js/firebase.database.Reference#set
* @param value
* @returns {*}
* @param onComplete
* @returns {Promise}
*/
set(value: any) {
return this._database._native.set(this.path, this._serializeAnyType(value));
set(value: any, onComplete?: Function): Promise {
return promiseOrCallback(
this._database._native.set(this.path, this._serializeAnyType(value)),
onComplete,
);
}
/**
* Sets a priority for the data at this Database location.
*
* @link https://firebase.google.com/docs/reference/js/firebase.database.Reference#setPriority
* @param priority
* @returns {*}
* @param onComplete
* @returns {Promise}
*/
setPriority(priority: string | number | null) {
setPriority(priority: string | number | null, onComplete?: Function): Promise {
const _priority = this._serializeAnyType(priority);
return this._database._native.setPriority(this.path, _priority);
return promiseOrCallback(
this._database._native.setPriority(this.path, _priority),
onComplete,
);
}
/**
* Writes data the Database location. Like set() but also specifies the priority for that data.
*
* @link https://firebase.google.com/docs/reference/js/firebase.database.Reference#setWithPriority
* @param value
* @param priority
* @returns {*}
* @param onComplete
* @returns {Promise}
*/
setWithPriority(value: any, priority: string | number | null) {
setWithPriority(value: any, priority: string | number | null, onComplete?: Function): Promise {
const _value = this._serializeAnyType(value);
const _priority = this._serializeAnyType(priority);
return this._database._native.setWithPriority(this.path, _value, _priority);
return promiseOrCallback(
this._database._native.setWithPriority(this.path, _value, _priority),
onComplete,
);
}
/**
* Writes multiple values to the Database at once.
*
* @link https://firebase.google.com/docs/reference/js/firebase.database.Reference#update
* @param val
* @returns {*}
* @param onComplete
* @returns {Promise}
*/
update(val: Object) {
update(val: Object, onComplete?: Function): Promise {
const value = this._serializeObject(val);
return this._database._native.update(this.path, value);
return promiseOrCallback(
this._database._native.update(this.path, value),
onComplete,
);
}
/**
* Removes the data at this Database location.
*
* @returns {*}
* @link https://firebase.google.com/docs/reference/js/firebase.database.Reference#remove
* @param onComplete
* @return {Promise}
*/
remove() {
return this._database._native.remove(this.path);
remove(onComplete?: Function): Promise {
return promiseOrCallback(
this._database._native.remove(this.path),
onComplete,
);
}
/**
* Atomically modifies the data at this location.
* @url https://firebase.google.com/docs/reference/js/firebase.database.Reference#transaction
*
* @link https://firebase.google.com/docs/reference/js/firebase.database.Reference#transaction
* @param transactionUpdate
* @param onComplete
* @param applyLocally
@ -140,6 +180,7 @@ export default class Reference extends ReferenceBase {
);
}
// todo cleanup / use new promiseOrCallback logic
return new Promise((resolve, reject) => {
const onCompleteWrapper = (error, committed, snapshotData) => {
if (error) {
@ -190,7 +231,7 @@ export default class Reference extends ReferenceBase {
* @param onComplete
* @returns {*}
*/
push(value: any, onComplete: Function) {
push(value: any, onComplete?: Function) {
if (value === null || value === undefined) {
return new Reference(this._database, `${this.path}/${generatePushID(this._database.serverTimeOffset)}`);
}
@ -218,7 +259,7 @@ export default class Reference extends ReferenceBase {
* @returns {Reference}
*/
orderByKey(): Reference {
return this.orderBy('orderByKey');
return this._query.orderBy('orderByKey');
}
/**
@ -226,7 +267,7 @@ export default class Reference extends ReferenceBase {
* @returns {Reference}
*/
orderByPriority(): Reference {
return this.orderBy('orderByPriority');
return this._query.orderBy('orderByPriority');
}
/**
@ -234,7 +275,7 @@ export default class Reference extends ReferenceBase {
* @returns {Reference}
*/
orderByValue(): Reference {
return this.orderBy('orderByValue');
return this._query.orderBy('orderByValue');
}
/**
@ -243,7 +284,7 @@ export default class Reference extends ReferenceBase {
* @returns {Reference}
*/
orderByChild(key: string): Reference {
return this.orderBy('orderByChild', key);
return this._query.orderBy('orderByChild', key);
}
/**
@ -254,7 +295,7 @@ export default class Reference extends ReferenceBase {
*/
orderBy(name: string, key?: string): Reference {
const newRef = new Reference(this._database, this.path, this._query.getModifiers());
newRef.query.orderBy(name, key);
newRef._query.orderBy(name, key);
return newRef;
}
@ -268,7 +309,7 @@ export default class Reference extends ReferenceBase {
* @returns {Reference}
*/
limitToLast(limit: number): Reference {
return this.limit('limitToLast', limit);
return this._query.limit('limitToLast', limit);
}
/**
@ -277,7 +318,7 @@ export default class Reference extends ReferenceBase {
* @returns {Reference}
*/
limitToFirst(limit: number): Reference {
return this.limit('limitToFirst', limit);
return this._query.limit('limitToFirst', limit);
}
/**
@ -288,7 +329,7 @@ export default class Reference extends ReferenceBase {
*/
limit(name: string, limit: number): Reference {
const newRef = new Reference(this._database, this.path, this._query.getModifiers());
newRef.query.limit(name, limit);
newRef._query.limit(name, limit);
return newRef;
}
@ -303,7 +344,7 @@ export default class Reference extends ReferenceBase {
* @returns {Reference}
*/
equalTo(value: any, key?: string): Reference {
return this.filter('equalTo', value, key);
return this._query.filter('equalTo', value, key);
}
/**
@ -313,7 +354,7 @@ export default class Reference extends ReferenceBase {
* @returns {Reference}
*/
endAt(value: any, key?: string): Reference {
return this.filter('endAt', value, key);
return this._query.filter('endAt', value, key);
}
/**
@ -323,7 +364,7 @@ export default class Reference extends ReferenceBase {
* @returns {Reference}
*/
startAt(value: any, key?: string): Reference {
return this.filter('startAt', value, key);
return this._query.filter('startAt', value, key);
}
/**
@ -335,7 +376,7 @@ export default class Reference extends ReferenceBase {
*/
filter(name: string, value: any, key?: string): Reference {
const newRef = new Reference(this._database, this.path, this._query.getModifiers());
newRef.query.filter(name, value, key);
newRef._query.filter(name, value, key);
return newRef;
}
@ -679,7 +720,6 @@ export default class Reference extends ReferenceBase {
* {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#off}
*/
off(eventType?: string = '', originalCallback?: () => any) {
// TODO this.log.debug('ref.off(): ', this._refId, eventType);
// $FlowFixMe
const listeners: Array<DatabaseListener> = Object.values(this._refListeners);
let listenersToRemove;

View File

@ -7,8 +7,6 @@ export default class ReferenceBase {
this.path = path || '/';
}
// todo add missing firebase reference props/methods
/**
* The last part of a Reference's path (after the last '/')
* The key of a root Reference is null.

View File

@ -307,3 +307,29 @@ export function nativeWithApp(appName, NativeModule) {
return native;
}
/**
* Return the existing promise if no callback provided or
* exec the promise and callback if optionalCallback is valid.
*
* @param promise
* @param optionalCallback
* @return {Promise}
*/
export function promiseOrCallback(promise: Promise, optionalCallback?: Function) {
if (!isFunction(optionalCallback)) return promise;
return promise.then((result) => {
// some of firebase internal tests & methods only check/return one arg
// see https://github.com/firebase/firebase-js-sdk/blob/master/src/utils/promise.ts#L62
if (optionalCallback.length === 1) {
optionalCallback(null);
} else {
optionalCallback(null, result);
}
return Promise.resolve(result);
}).catch((error) => {
optionalCallback(error);
return Promise.reject(error);
});
}