UNPKG

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
"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;