react-native-firebase-compiled
Version:
A well tested, feature rich Firebase implementation for React Native, supporting iOS & Android. Individual module support for Admob, Analytics, Auth, Crash Reporting, Cloud Firestore, Database, Dynamic Links, Functions, Messaging (FCM), Remote Config, Sto
311 lines (235 loc) • 11.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _DocumentSnapshot = _interopRequireDefault(require("./DocumentSnapshot"));
var _FieldPath = _interopRequireDefault(require("./FieldPath"));
var _QuerySnapshot = _interopRequireDefault(require("./QuerySnapshot"));
var _serialize = require("./utils/serialize");
var _events = require("../../utils/events");
var _log = require("../../utils/log");
var _utils = require("../../utils");
var _native = require("../../utils/native");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
const DIRECTIONS = {
ASC: 'ASCENDING',
asc: 'ASCENDING',
DESC: 'DESCENDING',
desc: 'DESCENDING'
};
const OPERATORS = {
'=': 'EQUAL',
'==': 'EQUAL',
'>': 'GREATER_THAN',
'>=': 'GREATER_THAN_OR_EQUAL',
'<': 'LESS_THAN',
'<=': 'LESS_THAN_OR_EQUAL'
};
const buildNativeFieldPath = fieldPath => {
if (fieldPath instanceof _FieldPath.default) {
return {
elements: fieldPath._segments,
type: 'fieldpath'
};
}
return {
string: fieldPath,
type: 'string'
};
};
/**
* @class Query
*/
class Query {
constructor(firestore, path, fieldFilters, fieldOrders, queryOptions) {
_defineProperty(this, "_fieldFilters", void 0);
_defineProperty(this, "_fieldOrders", void 0);
_defineProperty(this, "_firestore", void 0);
_defineProperty(this, "_iid", void 0);
_defineProperty(this, "_queryOptions", void 0);
_defineProperty(this, "_referencePath", void 0);
this._fieldFilters = fieldFilters || [];
this._fieldOrders = fieldOrders || [];
this._firestore = firestore;
this._queryOptions = queryOptions || {};
this._referencePath = path;
}
get firestore() {
return this._firestore;
}
endAt(...snapshotOrVarArgs) {
const options = _objectSpread({}, this._queryOptions, {
endAt: this._buildOrderByOption(snapshotOrVarArgs)
});
return new Query(this.firestore, this._referencePath, this._fieldFilters, this._fieldOrders, options);
}
endBefore(...snapshotOrVarArgs) {
const options = _objectSpread({}, this._queryOptions, {
endBefore: this._buildOrderByOption(snapshotOrVarArgs)
});
return new Query(this.firestore, this._referencePath, this._fieldFilters, this._fieldOrders, options);
}
get(options) {
if (options) {
if (!(0, _utils.isObject)(options)) {
return Promise.reject(new Error('Query.get failed: First argument must be an object.'));
}
if (options.source && options.source !== 'default' && options.source !== 'server' && options.source !== 'cache') {
return Promise.reject(new Error('Query.get failed: GetOptions.source must be one of `default`, `server` or `cache`.'));
}
}
return (0, _native.getNativeModule)(this._firestore).collectionGet(this._referencePath.relativeName, this._fieldFilters, this._fieldOrders, this._queryOptions, options).then(nativeData => new _QuerySnapshot.default(this._firestore, this, nativeData));
}
limit(limit) {
// TODO: Validation
// validate.isInteger('n', n);
const options = _objectSpread({}, this._queryOptions, {
limit
});
return new Query(this.firestore, this._referencePath, this._fieldFilters, this._fieldOrders, options);
}
onSnapshot(optionsOrObserverOrOnNext, observerOrOnNextOrOnError, onError) {
let observer;
let metadataChanges = {}; // Called with: onNext, ?onError
if ((0, _utils.isFunction)(optionsOrObserverOrOnNext)) {
if (observerOrOnNextOrOnError && !(0, _utils.isFunction)(observerOrOnNextOrOnError)) {
throw new Error('Query.onSnapshot failed: Second argument must be a valid function.');
} // $FlowExpectedError: Not coping with the overloaded method signature
observer = {
next: optionsOrObserverOrOnNext,
error: observerOrOnNextOrOnError
};
} else if (optionsOrObserverOrOnNext && (0, _utils.isObject)(optionsOrObserverOrOnNext)) {
// Called with: Observer
if (optionsOrObserverOrOnNext.next) {
if ((0, _utils.isFunction)(optionsOrObserverOrOnNext.next)) {
if (optionsOrObserverOrOnNext.error && !(0, _utils.isFunction)(optionsOrObserverOrOnNext.error)) {
throw new Error('Query.onSnapshot failed: Observer.error must be a valid function.');
} // $FlowExpectedError: Not coping with the overloaded method signature
observer = {
next: optionsOrObserverOrOnNext.next,
error: optionsOrObserverOrOnNext.error
};
} else {
throw new Error('Query.onSnapshot failed: Observer.next must be a valid function.');
}
} else if (Object.prototype.hasOwnProperty.call(optionsOrObserverOrOnNext, 'includeMetadataChanges')) {
metadataChanges = optionsOrObserverOrOnNext; // Called with: Options, onNext, ?onError
if ((0, _utils.isFunction)(observerOrOnNextOrOnError)) {
if (onError && !(0, _utils.isFunction)(onError)) {
throw new Error('Query.onSnapshot failed: Third argument must be a valid function.');
} // $FlowExpectedError: Not coping with the overloaded method signature
observer = {
next: observerOrOnNextOrOnError,
error: onError
}; // Called with Options, Observer
} else if (observerOrOnNextOrOnError && (0, _utils.isObject)(observerOrOnNextOrOnError) && observerOrOnNextOrOnError.next) {
if ((0, _utils.isFunction)(observerOrOnNextOrOnError.next)) {
if (observerOrOnNextOrOnError.error && !(0, _utils.isFunction)(observerOrOnNextOrOnError.error)) {
throw new Error('Query.onSnapshot failed: Observer.error must be a valid function.');
}
observer = {
next: observerOrOnNextOrOnError.next,
error: observerOrOnNextOrOnError.error
};
} else {
throw new Error('Query.onSnapshot failed: Observer.next must be a valid function.');
}
} else {
throw new Error('Query.onSnapshot failed: Second argument must be a function or observer.');
}
} else {
throw new Error('Query.onSnapshot failed: First argument must be a function, observer or options.');
}
} else {
throw new Error('Query.onSnapshot failed: Called with invalid arguments.');
}
const listenerId = (0, _utils.firestoreAutoId)();
const listener = nativeQuerySnapshot => {
const querySnapshot = new _QuerySnapshot.default(this._firestore, this, nativeQuerySnapshot);
observer.next(querySnapshot);
}; // Listen to snapshot events
_events.SharedEventEmitter.addListener((0, _events.getAppEventName)(this._firestore, `onQuerySnapshot:${listenerId}`), listener); // Listen for snapshot error events
if (observer.error) {
_events.SharedEventEmitter.addListener((0, _events.getAppEventName)(this._firestore, `onQuerySnapshotError:${listenerId}`), observer.error);
} // Add the native listener
(0, _native.getNativeModule)(this._firestore).collectionOnSnapshot(this._referencePath.relativeName, this._fieldFilters, this._fieldOrders, this._queryOptions, listenerId, metadataChanges); // Return an unsubscribe method
return this._offCollectionSnapshot.bind(this, listenerId, listener);
}
orderBy(fieldPath, directionStr = 'asc') {
// TODO: Validation
// validate.isFieldPath('fieldPath', fieldPath);
// validate.isOptionalFieldOrder('directionStr', directionStr);
if (this._queryOptions.startAt || this._queryOptions.startAfter || this._queryOptions.endAt || this._queryOptions.endBefore) {
throw new Error('Cannot specify an orderBy() constraint after calling ' + 'startAt(), startAfter(), endBefore() or endAt().');
}
const newOrder = {
direction: DIRECTIONS[directionStr],
fieldPath: buildNativeFieldPath(fieldPath)
};
const combinedOrders = this._fieldOrders.concat(newOrder);
return new Query(this.firestore, this._referencePath, this._fieldFilters, combinedOrders, this._queryOptions);
}
startAfter(...snapshotOrVarArgs) {
const options = _objectSpread({}, this._queryOptions, {
startAfter: this._buildOrderByOption(snapshotOrVarArgs)
});
return new Query(this.firestore, this._referencePath, this._fieldFilters, this._fieldOrders, options);
}
startAt(...snapshotOrVarArgs) {
const options = _objectSpread({}, this._queryOptions, {
startAt: this._buildOrderByOption(snapshotOrVarArgs)
});
return new Query(this.firestore, this._referencePath, this._fieldFilters, this._fieldOrders, options);
}
where(fieldPath, opStr, value) {
// TODO: Validation
// validate.isFieldPath('fieldPath', fieldPath);
// validate.isFieldFilter('fieldFilter', opStr, value);
const nativeValue = (0, _serialize.buildTypeMap)(value);
const newFilter = {
fieldPath: buildNativeFieldPath(fieldPath),
operator: OPERATORS[opStr],
value: nativeValue
};
const combinedFilters = this._fieldFilters.concat(newFilter);
return new Query(this.firestore, this._referencePath, combinedFilters, this._fieldOrders, this._queryOptions);
}
/**
* INTERNALS
*/
_buildOrderByOption(snapshotOrVarArgs) {
// TODO: Validation
let values;
if (snapshotOrVarArgs.length === 1 && snapshotOrVarArgs[0] instanceof _DocumentSnapshot.default) {
const docSnapshot = snapshotOrVarArgs[0];
values = [];
for (let i = 0; i < this._fieldOrders.length; i++) {
const fieldOrder = this._fieldOrders[i];
if (fieldOrder.fieldPath.type === 'string' && fieldOrder.fieldPath.string) {
values.push(docSnapshot.get(fieldOrder.fieldPath.string));
} else if (fieldOrder.fieldPath.elements) {
const fieldPath = new _FieldPath.default(...fieldOrder.fieldPath.elements);
values.push(docSnapshot.get(fieldPath));
}
}
} else {
values = snapshotOrVarArgs;
}
return (0, _serialize.buildNativeArray)(values);
}
/**
* Remove query snapshot listener
* @param listener
*/
_offCollectionSnapshot(listenerId, listener) {
(0, _log.getLogger)(this._firestore).info('Removing onQuerySnapshot listener');
_events.SharedEventEmitter.removeListener((0, _events.getAppEventName)(this._firestore, `onQuerySnapshot:${listenerId}`), listener);
_events.SharedEventEmitter.removeListener((0, _events.getAppEventName)(this._firestore, `onQuerySnapshotError:${listenerId}`), listener);
(0, _native.getNativeModule)(this._firestore).collectionOffSnapshot(this._referencePath.relativeName, this._fieldFilters, this._fieldOrders, this._queryOptions, listenerId);
}
}
exports.default = Query;