UNPKG

@react-native-firebase/firestore

Version:

React Native Firebase - Cloud Firestore is a NoSQL cloud database to store and sync data between your React Native application and Firebase's database. The API matches the Firebase Web SDK whilst taking advantage of the native SDKs performance and offline

1,506 lines (1,406 loc) 81.9 kB
/* * Copyright (c) 2016-present Invertase Limited & Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this library except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import { ReactNativeFirebase } from '@react-native-firebase/app'; /** * Firebase Cloud Firestore package for React Native. * * #### Example: Access the firebase export from the `firestore` package: * * ```js * import { firebase } from '@react-native-firebase/firestore'; * * // firebase.firestore().X * ``` * * #### Example: Using the default export from the `firestore` package: * * ```js * import firestore from '@react-native-firebase/firestore'; * * // firestore().X * ``` * * #### Example: Using the default export from the `app` package: * * ```js * import firebase from '@react-native-firebase/app'; * import '@react-native-firebase/firestore'; * * // firebase.firestore().X * ``` * * @firebase firestore */ export namespace FirebaseFirestoreTypes { import FirebaseModule = ReactNativeFirebase.FirebaseModule; /** * An instance of Filter used to generate Firestore Filter queries. */ export type QueryFilterType = 'OR' | 'AND'; export interface QueryFieldFilterConstraint { fieldPath: keyof T | FieldPath; operator: WhereFilterOp; value: any; } export interface QueryCompositeFilterConstraint { operator: QueryFilterType; queries: QueryFieldFilterConstraint[]; } export type QueryFilterConstraint = QueryFieldFilterConstraint | QueryCompositeFilterConstraint; /** * The Filter functions used to generate an instance of Filter. */ export interface FilterFunction { /** * The Filter function used to generate an instance of Filter. * e.g. Filter('name', '==', 'Ada') */ ( fieldPath: keyof T | FieldPath, operator: WhereFilterOp, value: any, ): QueryFieldFilterConstraint; /** * The Filter.or() static function used to generate a logical OR query using multiple Filter instances. * e.g. Filter.or(Filter('name', '==', 'Ada'), Filter('name', '==', 'Bob')) */ or(...queries: QueryFilterConstraint[]): QueryCompositeFilterConstraint; /** * The Filter.and() static function used to generate a logical AND query using multiple Filter instances. * e.g. Filter.and(Filter('name', '==', 'Ada'), Filter('name', '==', 'Bob')) */ and(...queries: QueryFilterConstraint[]): QueryCompositeFilterConstraint; } /** * The Filter function used to generate an instance of Filter. * e.g. Filter('name', '==', 'Ada') */ export const Filter: FilterFunction; /** * An immutable object representing an array of bytes. */ export class Blob { /** * Creates a new Blob from the given Base64 string, converting it to bytes. * * @param base64 The Base64 string used to create the Blob object. */ static fromBase64String(base64: string): Blob; /** * Creates a new Blob from the given Uint8Array. * * @param array The Uint8Array used to create the Blob object. */ static fromUint8Array(array: Uint8Array): Blob; /** * Returns true if this `Blob` is equal to the provided one. * * @param other The `Blob` to compare against. */ isEqual(other: Blob): boolean; /** * Returns the bytes of a Blob as a Base64-encoded string. */ toBase64(): string; /** * Returns the bytes of a Blob in a new Uint8Array. */ toUint8Array(): Uint8Array; } /** * A `DocumentData` object represents the data in a document. */ export interface DocumentData { [key: string]: any; } /** * A `CollectionReference` object can be used for adding documents, getting document references, and querying for * documents (using the methods inherited from `Query`). */ export interface CollectionReference<T extends DocumentData = DocumentData> extends Query<T> { /** * The collection's identifier. */ id: string; /** * A reference to the containing `DocumentReference` if this is a subcollection. If this isn't a * subcollection, the reference is null. */ parent: DocumentReference | null; /** * A string representing the path of the referenced collection (relative to the root of the database). */ path: string; /** * Add a new document to this collection with the specified data, assigning it a document ID automatically. * * #### Example * * ```js * const documentRef = await firebase.firestore().collection('users').add({ * name: 'Ada Lovelace', * age: 30, * }); * ``` * * @param data An Object containing the data for the new document. */ add(data: T): Promise<DocumentReference<T>>; /** * Get a DocumentReference for the document within the collection at the specified path. If no * path is specified, an automatically-generated unique ID will be used for the returned DocumentReference. * * #### Example * * ```js * await firebase.firestore().collection('users').doc('alovelace').set({ * name: 'Ada Lovelace', * age: 30, * }); * ``` * * @param documentPath A slash-separated path to a document. */ doc(documentPath?: string): DocumentReference<T>; } /** * A DocumentChange represents a change to the documents matching a query. It contains the document affected and the * type of change that occurred. */ export interface DocumentChange<T extends DocumentData = DocumentData> { /** * The document affected by this change. */ doc: QueryDocumentSnapshot<T>; /** * The index of the changed document in the result set immediately after this `DocumentChange` * (i.e. supposing that all prior `DocumentChange` objects and the current `DocumentChange` object have been applied). * Is -1 for 'removed' events. */ newIndex: number; /** * The index of the changed document in the result set immediately prior to this `DocumentChange` (i.e. * supposing that all prior `DocumentChange` objects have been applied). Is -1 for 'added' events. */ oldIndex: number; /** * The type of change ('added', 'modified', or 'removed'). */ type: DocumentChangeType; } /** * The type of a DocumentChange may be 'added', 'removed', or 'modified'. */ export type DocumentChangeType = 'added' | 'removed' | 'modified'; /** * The types for a DocumentSnapshot field that are supported by Firestore. */ export type DocumentFieldType = | string | number | boolean | { [key: string]: DocumentFieldType } | DocumentFieldType[] | null | Timestamp | GeoPoint | Blob | FieldPath | FieldValue | DocumentReference | CollectionReference; /** * A `DocumentReference` refers to a document location in a Firestore database and can be used to write, read, or listen * to the location. The document at the referenced location may or may not exist. A `DocumentReference` can also be used * to create a `CollectionReference` to a subcollection. */ export interface DocumentReference<T extends DocumentData = DocumentData> { /** * The Firestore instance the document is in. This is useful for performing transactions, for example. */ firestore: Module; /** * The document's identifier within its collection. */ id: string; /** * The Collection this `DocumentReference` belongs to. */ parent: CollectionReference<T>; /** * A string representing the path of the referenced document (relative to the root of the database). */ path: string; /** * Gets a `CollectionReference` instance that refers to the collection at the specified path. * * #### Example * * ```js * const collectionRef = firebase.firestore().doc('users/alovelace').collection('orders'); * ``` * * @param collectionPath A slash-separated path to a collection. */ collection(collectionPath: string): CollectionReference; /** * Deletes the document referred to by this DocumentReference. * * #### Example * * ```js * await firebase.firestore().doc('users/alovelace').delete(); * ``` * * The Promise is resolved once the document has been successfully deleted from the backend * (Note that it won't resolve while you're offline). */ delete(): Promise<void>; /** * Reads the document referred to by this DocumentReference. * * Note: By default, get() attempts to provide up-to-date data when possible by waiting for data * from the server, but it may return cached data or fail if you are offline and the server cannot * be reached. This behavior can be altered via the GetOptions parameter. * * #### Example * * ```js * await firebase.firestore().doc('users/alovelace').get({ * source: 'server', * }); * ``` * * @param options An object to configure the get behavior. */ get(options?: GetOptions): Promise<DocumentSnapshot<T>>; /** * Returns true if this DocumentReference is equal to the provided one. * * #### Example * * ```js * const alovelace = firebase.firestore().doc('users/alovelace'); * const dsmith = firebase.firestore().doc('users/dsmith'); * * // false * alovelace.isEqual(dsmith); * ``` * * @param other The `DocumentReference` to compare against. */ isEqual(other: DocumentReference): boolean; /** * Attaches a listener for DocumentSnapshot events. * * NOTE: Although an complete callback can be provided, it will never be called because the snapshot stream is never-ending. * * Returns an unsubscribe function to stop listening to events. * * #### Example * * ```js * const unsubscribe = firebase.firestore().doc('users/alovelace') * .onSnapshot({ * error: (e) => console.error(e), * next: (documentSnapshot) => {}, * }); * * unsubscribe(); * ``` * * @param observer A single object containing `next` and `error` callbacks. */ onSnapshot(observer: { complete?: () => void; error?: (error: Error) => void; next?: (snapshot: DocumentSnapshot<T>) => void; }): () => void; /** * Attaches a listener for DocumentSnapshot events with snapshot listener options. * * NOTE: Although an complete callback can be provided, it will never be called because the snapshot stream is never-ending. * * Returns an unsubscribe function to stop listening to events. * * #### Example * * ```js * const unsubscribe = firebase.firestore().doc('users/alovelace') * .onSnapshot({ * includeMetadataChanges: true, * }, { * error: (e) => console.error(e), * next: (documentSnapshot) => {}, * }); * * unsubscribe(); * ``` * * @param options Options controlling the listen behavior. * @param observer A single object containing `next` and `error` callbacks. */ onSnapshot( options: SnapshotListenOptions, observer: { complete?: () => void; error?: (error: Error) => void; next?: (snapshot: DocumentSnapshot<T>) => void; }, ): () => void; /** * Attaches a listener for DocumentSnapshot events. * * NOTE: Although an onCompletion callback can be provided, it will never be called because the snapshot stream is never-ending. * * Returns an unsubscribe function to stop listening to events. * * #### Example * * ```js * const unsubscribe = firebase.firestore().doc('users/alovelace') * .onSnapshot( * (documentSnapshot) => {}, // onNext * (error) => console.error(error), // onError * ); * * unsubscribe(); * ``` * @param onNext A callback to be called every time a new `DocumentSnapshot` is available. * @param onError A callback to be called if the listen fails or is cancelled. No further callbacks will occur. * @param onCompletion An optional function which will never be called. */ onSnapshot( onNext: (snapshot: DocumentSnapshot<T>) => void, onError?: (error: Error) => void, onCompletion?: () => void, ): () => void; /** * Attaches a listener for DocumentSnapshot events with snapshot listener options. * * NOTE: Although an onCompletion callback can be provided, it will never be called because the snapshot stream is never-ending. * * Returns an unsubscribe function to stop listening to events. * * #### Example * * ```js * const unsubscribe = firebase.firestore().doc('users/alovelace') * .onSnapshot( * { includeMetadataChanges: true }, // SnapshotListenerOptions * (documentSnapshot) => {}, // onNext * (error) => console.error(error), // onError * ); * * unsubscribe(); * ``` * @param options Options controlling the listen behavior. * @param onNext A callback to be called every time a new `DocumentSnapshot` is available. * @param onError A callback to be called if the listen fails or is cancelled. No further callbacks will occur. * @param onCompletion An optional function which will never be called. */ onSnapshot( options: SnapshotListenOptions, onNext: (snapshot: DocumentSnapshot<T>) => void, onError?: (error: Error) => void, onCompletion?: () => void, ): () => void; /** * Writes to the document referred to by this DocumentReference. If the document does not yet * exist, it will be created. If you pass SetOptions, the provided data can be merged into an * existing document. * * #### Example * * ```js * const user = firebase.firestore().doc('users/alovelace'); * * // Set new data * await user.set({ * name: 'Ada Lovelace', * age: 30, * city: 'LON', * }); * ``` * * @param data A map of the fields and values for the document. * @param options An object to configure the set behavior. */ set(data: SetValue<T>, options?: SetOptions): Promise<void>; /** * Updates fields in the document referred to by this `DocumentReference`. The update will fail * if applied to a document that does not exist. * * #### Example * * ``` * const user = firebase.firestore().doc('users/alovelace'); * * // Update age but leave other fields untouched * await user.update({ * age: 31, * }); * ``` * * @param data An object containing the fields and values with which to update the document. Fields can contain dots to reference nested fields within the document. */ update(data: Partial<SetValue<T>>): Promise<void>; /** * Updates fields in the document referred to by this DocumentReference. The update will fail if * applied to a document that does not exist. * * #### Example * * ``` * const user = firebase.firestore().doc('users/alovelace'); * * // Update age & city but leve other fields untouched * await user.update('age', 31, 'city', 'SF'); * ``` * * @param field The first field to update. * @param value The first value. * @param moreFieldsAndValues Additional key value pairs. */ update(field: keyof T | FieldPath, value: any, ...moreFieldsAndValues: any[]): Promise<void>; } /** * A DocumentSnapshot contains data read from a document in your Firestore database. The data can be extracted with * .`data()` or `.get(:field)` to get a specific field. * * For a DocumentSnapshot that points to a non-existing document, any data access will return 'undefined'. * You can use the `exists` property to explicitly verify a document's existence. */ export interface DocumentSnapshot<T extends DocumentData = DocumentData> { /** * Property of the `DocumentSnapshot` that signals whether or not the data exists. True if the document exists. */ exists: boolean; /** * Property of the `DocumentSnapshot` that provides the document's ID. */ id: string; /** * Metadata about the `DocumentSnapshot`, including information about its source and local modifications. */ metadata: SnapshotMetadata; /** * The `DocumentReference` for the document included in the `DocumentSnapshot`. */ ref: DocumentReference<T>; /** * Retrieves all fields in the document as an Object. Returns 'undefined' if the document doesn't exist. * * #### Example * * ```js * const user = await firebase.firestore().doc('users/alovelace').get(); * * console.log('User', user.data()); * ``` */ data(): T | undefined; /** * Retrieves the field specified by fieldPath. Returns undefined if the document or field doesn't exist. * * #### Example * * ```js * const user = await firebase.firestore().doc('users/alovelace').get(); * * console.log('Address ZIP Code', user.get('address.zip')); * ``` * * @param fieldPath The path (e.g. 'foo' or 'foo.bar') to a specific field. */ get<fieldType extends DocumentFieldType>(fieldPath: keyof T | string | FieldPath): fieldType; /** * Returns true if this `DocumentSnapshot` is equal to the provided one. * * #### Example * * ```js * const user1 = await firebase.firestore().doc('users/alovelace').get(); * const user2 = await firebase.firestore().doc('users/dsmith').get(); * * // false * user1.isEqual(user2); * ``` * * @param other The `DocumentSnapshot` to compare against. */ isEqual(other: DocumentSnapshot): boolean; } /** * A QueryDocumentSnapshot contains data read from a document in your Firestore database as part of a query. * The document is guaranteed to exist and its data can be extracted with .data() or .get(:field) to get a specific field. * * A QueryDocumentSnapshot offers the same API surface as a DocumentSnapshot. * Since query results contain only existing documents, the exists property will always be true and data() will never return 'undefined'. */ export interface QueryDocumentSnapshot<T extends DocumentData = DocumentData> extends DocumentSnapshot<T> { /** * A QueryDocumentSnapshot is always guaranteed to exist. */ exists: true; /** * Retrieves all fields in the document as an Object. * * #### Example * * ```js * const users = await firebase.firestore().collection('users').get(); * * for (const user of users.docs) { * console.log('User', user.data()); * } * ``` */ data(): T; } /** * A FieldPath refers to a field in a document. The path may consist of a single field name (referring to a * top-level field in the document), or a list of field names (referring to a nested field in the document). * * Create a FieldPath by providing field names. If more than one field name is provided, the path will point to a nested field in a document. * * #### Example * * ```js * const user = await firebase.firestore().doc('users/alovelace').get(); * * // Create a new field path * const fieldPath = new firebase.firestore.FieldPath('address', 'zip'); * * console.log('Address ZIP Code', user.get(fieldPath)); * ``` */ export class FieldPath { /** * Returns a special sentinel `FieldPath` to refer to the ID of a document. It can be used in queries to sort or filter by the document ID. */ static documentId(): FieldPath; /** * Creates a FieldPath from the provided field names. If more than one field name is provided, the path will point to a nested field in a document. * * #### Example * * ```js * const fieldPath = new firebase.firestore.FieldPath('address', line', 'one'); * ``` * * @param fieldNames A list of field names. */ constructor(...fieldNames: string[]); /** * Returns true if this `FieldPath` is equal to the provided one. * * #### Example * * ```js * const fieldPath1 = new firebase.firestore.FieldPath('address', 'zip'); * const fieldPath2 = new firebase.firestore.FieldPath('address', line', 'one'); * * // false * fieldPath1.isEqual(fieldPath2); * ``` * * @param other The `FieldPath` to compare against. */ isEqual(other: FieldPath): boolean; } /** * Sentinel values that can be used when writing document fields with `set()` or `update()`. * * #### Example * * ```js * const increment = firebase.firestore.FieldValue.increment(1); * * await firebase.firestore().doc('users/alovelace').update({ * age: increment, // increment age by 1 * }); * ``` */ export class FieldValue { /** * Returns a special value that can be used with `set()` or `update()` that tells the server to remove the given elements * from any array value that already exists on the server. All instances of each element specified will be removed from * the array. If the field being modified is not already an array it will be overwritten with an empty array. * * #### Example * * ```js * const arrayRemove = firebase.firestore.FieldValue.arrayRemove(2, '3'); * * // Removes the values 2 & '3' from the values array on the document * await docRef.update({ * values: arrayRemove, * }); * ``` * * @param elements The elements to remove from the array. */ static arrayRemove(...elements: any[]): FieldValue; /** * Returns a special value that can be used with `set()` or `update()` that tells the server to union the given * elements with any array value that already exists on the server. Each specified element that doesn't already exist * in the array will be added to the end. If the field being modified is not already an array it will be overwritten * with an array containing exactly the specified elements. * * #### Example * * ```js * const arrayUnion = firebase.firestore.FieldValue.arrayUnion(2, '3'); * * // Appends the values 2 & '3' onto the values array on the document * await docRef.update({ * values: arrayUnion, * }); * ``` * * @param elements The elements to union into the array. */ static arrayUnion(...elements: any[]): FieldValue; /** * Returns a sentinel for use with update() to mark a field for deletion. * * #### Example * * ```js * const delete = firebase.firestore.FieldValue.delete(); * * // Deletes the name field on the document * await docRef.update({ * name: delete, * }); * ``` */ static delete(): FieldValue; /** * Returns a special value that can be used with `set()` or `update()` that tells the server to increment the field's current value by the given value. * * If either the operand or the current field value uses floating point precision, all arithmetic follows IEEE 754 semantics. * If both values are integers, values outside of JavaScript's safe number range (`Number.MIN_SAFE_INTEGER` to `Number.MAX_SAFE_INTEGER`) * are also subject to precision loss. Furthermore, once processed by the Firestore backend, all integer operations are * capped between -2^63 and 2^63-1. * * If the current field value is not of type `number`, or if the field does not yet exist, the transformation sets the field to the given value. * * #### Example * * ```js * const increment = firebase.firestore.FieldValue.increment(1); * * // Increment the loginCount field by 1 on the document * await docRef.update({ * loginCount: increment, * }); * ``` * * Please be careful using this operator. It may not be reliable enough for use in circumstances where absolute accuracy is required, * as it appears writes to Firestore may sometimes be duplicated in situations not fully understood yet, but possibly correlated with * write frequency. See https://github.com/invertase/react-native-firebase/discussions/5914 * * @param n The value to increment by. */ static increment(n: number): FieldValue; /** * Returns a sentinel used with set() or update() to include a server-generated timestamp in the written data. * * #### Example * * ```js * const timestamp = firebase.firestore.FieldValue.serverTimestamp(); * * // Set the updatedAt field to the current server time * await docRef.update({ * updatedAt: timestamp, * }); * ``` */ static serverTimestamp(): FieldValue; /** * Returns true if this `FieldValue` is equal to the provided one. * * #### Example * * ```js * const increment = firebase.firestore.FieldValue.increment(1); * const timestamp = firebase.firestore.FieldValue.serverTimestamp(); * * // false * increment.isEqual(timestamp); * ``` * * @param other The `FieldValue` to compare against. */ isEqual(other: FieldValue): boolean; } /** * An immutable object representing a geo point in Firestore. The geo point is represented as latitude/longitude pair. * * Latitude values are in the range of [-90, 90]. Longitude values are in the range of [-180, 180]. */ export class GeoPoint { /** * Creates a new immutable GeoPoint object with the provided latitude and longitude values. * * #### Example * * ```js * const geoPoint = new firebase.firestore.GeoPoint(60, -40); * ``` * * @param latitude The latitude as number between -90 and 90. * @param longitude The longitude as number between -180 and 180. */ constructor(latitude: number, longitude: number); /** * The latitude of this `GeoPoint` instance. */ latitude: number; /** * The longitude of this `GeoPoint` instance. */ longitude: number; /** * Returns true if this `GeoPoint` is equal to the provided one. * * #### Example * * ```js * const geoPoint1 = new firebase.firestore.GeoPoint(60, -40); * const geoPoint2 = new firebase.firestore.GeoPoint(60, -20); * * // false * geoPoint1.isEqual(geoPoint2); * ``` * * @param other The `GeoPoint` to compare against. */ isEqual(other: GeoPoint): boolean; /** * Returns a JSON-serializable representation of this GeoPoint. */ toJSON(): { latitude: number; longitude: number }; } /** * An options object that configures the behavior of get() calls on DocumentReference and Query. * By providing a GetOptions object, these methods can be configured to fetch results only from the * server, only from the local cache or attempt to fetch results from the server and fall back to the * cache (which is the default). */ export interface GetOptions { /** * Describes whether we should get from server or cache. * * Setting to `default` (or not setting at all), causes Firestore to try to retrieve an up-to-date (server-retrieved) * snapshot, but fall back to returning cached data if the server can't be reached. * * Setting to `server` causes Firestore to avoid the cache, generating an error if the server cannot be reached. Note * that the cache will still be updated if the server request succeeds. Also note that latency-compensation still * takes effect, so any pending write operations will be visible in the returned data (merged into the server-provided data). * * Setting to `cache` causes Firestore to immediately return a value from the cache, ignoring the server completely * (implying that the returned value may be stale with respect to the value on the server.) If there is no data in the * cache to satisfy the `get()` call, `DocumentReference.get()` will return an error and `QuerySnapshot.get()` will return an * empty `QuerySnapshot` with no documents. */ source: 'default' | 'server' | 'cache'; } /** * Represents an aggregation that can be performed by Firestore. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars export class AggregateField<T> { /** A type string to uniquely identify instances of this class. */ type = 'AggregateField'; } /** * The union of all `AggregateField` types that are supported by Firestore. */ export type AggregateFieldType = AggregateField<number>; /** * A type whose property values are all `AggregateField` objects. */ export interface AggregateSpec { [field: string]: AggregateFieldType; } /** * A type whose keys are taken from an `AggregateSpec`, and whose values are the * result of the aggregation performed by the corresponding `AggregateField` * from the input `AggregateSpec`. */ export type AggregateSpecData<T extends AggregateSpec> = { [P in keyof T]: T[P] extends AggregateField<infer U> ? U : never; }; /** * The results of executing an aggregation query. */ export interface AggregateQuerySnapshot< AggregateSpecType extends AggregateSpec, AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData, > { /** * The underlying query over which the aggregations recorded in this * `AggregateQuerySnapshot` were performed. */ get query(): Query<AppModelType, DbModelType>; /** * Returns the results of the aggregations performed over the underlying * query. * * The keys of the returned object will be the same as those of the * `AggregateSpec` object specified to the aggregation method, and the values * will be the corresponding aggregation result. * * @returns The results of the aggregations performed over the underlying * query. */ data(): AggregateSpecData<AggregateSpecType>; } /** * The results of requesting an aggregated query. */ export interface AggregateQuery<T extends AggregateSpec> { /** * The underlying query for this instance. */ get query(): Query<unknown>; /** * Executes the query and returns the results as a AggregateQuerySnapshot. * * * #### Example * * ```js * const querySnapshot = await firebase.firestore() * .collection('users') * .count() * .get(); * ``` * * @param options An object to configure the get behavior. */ get(): Promise<AggregateQuerySnapshot<T>>; } /** * A Query refers to a `Query` which you can read or listen to. You can also construct refined `Query` objects by * adding filters and ordering. */ export interface Query<T extends DocumentData = DocumentData> { /** * Calculates the number of documents in the result set of the given query, without actually downloading * the documents. * * Using this function to count the documents is efficient because only the final count, not the * documents' data, is downloaded. This function can even count the documents if the result set * would be prohibitively large to download entirely (e.g. thousands of documents). * * The result received from the server is presented, unaltered, without considering any local state. * That is, documents in the local cache are not taken into consideration, neither are local * modifications not yet synchronized with the server. Previously-downloaded results, if any, * are not used: every request using this source necessarily involves a round trip to the server. */ count(): AggregateQuery<{ count: AggregateField<number> }>; /** * Same as count() */ countFromServer(): AggregateQuery<{ count: AggregateField<number> }>; /** * Creates and returns a new Query that ends at the provided document (inclusive). The end * position is relative to the order of the query. The document must contain all of the * fields provided in the orderBy of this query. * * #### Example * * ```js * const user = await firebase.firestore().doc('users/alovelace').get(); * * // Get all users up to a specific user in order of age * const querySnapshot = await firebase.firestore() * .collection('users') * .orderBy('age') * .endAt(user); * ``` * * > Cursor snapshot queries have limitations. Please see [Query limitations](/query-limitations) for more information. * * @param snapshot The snapshot of the document to end at. */ endAt(snapshot: DocumentSnapshot<T>): Query<T>; /** * Creates and returns a new Query that ends at the provided fields relative to the order of the query. * The order of the field values must match the order of the order by clauses of the query. * * #### Example * * ```js * // Get all users who's age is 30 or less * const querySnapshot = await firebase.firestore() * .collection('users') * .orderBy('age') * .endAt(30); * ``` * * @param fieldValues The field values to end this query at, in order of the query's order by. */ endAt(...fieldValues: any[]): Query<T>; /** * Creates and returns a new Query that ends before the provided document (exclusive). The end * position is relative to the order of the query. The document must contain all of the fields * provided in the orderBy of this query. * * #### Example * * ```js * const user = await firebase.firestore().doc('users/alovelace').get(); * * // Get all users up to, but not including, a specific user in order of age * const querySnapshot = await firebase.firestore() * .collection('users') * .orderBy('age') * .endBefore(user); * ``` * * > Cursor snapshot queries have limitations. Please see [Query limitations](/query-limitations) for more information. * * @param snapshot The snapshot of the document to end before. */ endBefore(snapshot: DocumentSnapshot<T>): Query<T>; /** * Creates and returns a new Query that ends before the provided fields relative to the order of * the query. The order of the field values must match the order of the order by clauses of the query. * * #### Example * * ```js * // Get all users who's age is 29 or less * const querySnapshot = await firebase.firestore() * .collection('users') * .orderBy('age') * .endBefore(30); * ``` * * @param fieldValues The field values to end this query before, in order of the query's order by. */ endBefore(...fieldValues: any[]): Query<T>; /** * Executes the query and returns the results as a QuerySnapshot. * * Note: By default, get() attempts to provide up-to-date data when possible by waiting for data from the server, * but it may return cached data or fail if you are offline and the server cannot be reached. This behavior can be * altered via the `GetOptions` parameter. * * #### Example * * ```js * const querySnapshot = await firebase.firestore() * .collection('users') * .orderBy('age') * .get({ * source: 'server', * }); * ``` * * @param options An object to configure the get behavior. */ get(options?: GetOptions): Promise<QuerySnapshot<T>>; /** * Returns true if this Query is equal to the provided one. * * #### Example * * ```js * const query = firebase.firestore() * .collection('users') * .orderBy('age'); * * // false * query.isEqual( * firebase.firestore() * .collection('users') * .orderBy('name') * ); * ``` * * @param other The `Query` to compare against. */ isEqual(other: Query): boolean; /** * Creates and returns a new Query where the results are limited to the specified number of documents. * * #### Example * * ```js * // Get 10 users in order of age * const querySnapshot = firebase.firestore() * .collection('users') * .orderBy('age') * .limit(10) * .get(); * ``` * * @param limit The maximum number of items to return. */ limit(limit: number): Query<T>; /** * Creates and returns a new Query where the results are limited to the specified number of documents * starting from the last document. The order is dependent on the second parameter for the `orderBy` * method. If `desc` is used, the order is reversed. `orderBy` method call is required when calling `limitToLast`. * * #### Example * * ```js * // Get the last 10 users in reverse order of age * const querySnapshot = firebase.firestore() * .collection('users') * .orderBy('age', 'desc') * .limitToLast(10) * .get(); * ``` * * @param limitToLast The maximum number of items to return. */ limitToLast(limitToLast: number): Query<T>; /** * Attaches a listener for `QuerySnapshot` events. * * > Although an `onCompletion` callback can be provided, it will never be called because the snapshot stream is never-ending. * * Returns an unsubscribe function to stop listening to events. * * #### Example * * ```js * const unsubscribe = firebase.firestore().collection('users') * .onSnapshot({ * error: (e) => console.error(e), * next: (querySnapshot) => {}, * }); * * unsubscribe(); * ``` * * @param observer A single object containing `next` and `error` callbacks. */ onSnapshot(observer: { complete?: () => void; error?: (error: Error) => void; next?: (snapshot: QuerySnapshot<T>) => void; }): () => void; /** * Attaches a listener for `QuerySnapshot` events with snapshot listener options. * * > Although an `onCompletion` callback can be provided, it will never be called because the snapshot stream is never-ending. * * Returns an unsubscribe function to stop listening to events. * * #### Example * * ```js * const unsubscribe = firebase.firestore().collection('users') * .onSnapshot({ * includeMetadataChanges: true, * }, { * error: (e) => console.error(e), * next: (querySnapshot) => {}, * }); * * unsubscribe(); * ``` * * @param options Options controlling the listen behavior. * @param observer A single object containing `next` and `error` callbacks. */ onSnapshot( options: SnapshotListenOptions, observer: { complete?: () => void; error?: (error: Error) => void; next?: (snapshot: QuerySnapshot<T>) => void; }, ): () => void; /** * Attaches a listener for `QuerySnapshot` events. * * > Although an `onCompletion` callback can be provided, it will never be called because the snapshot stream is never-ending. * * Returns an unsubscribe function to stop listening to events. * * #### Example * * ```js * const unsubscribe = firebase.firestore().collection('users') * .onSnapshot( * (querySnapshot) => {}, // onNext * (error) => console.error(error), // onError * ); * * unsubscribe(); * ``` * @param onNext A callback to be called every time a new `QuerySnapshot` is available. * @param onError A callback to be called if the listen fails or is cancelled. No further callbacks will occur. * @param onCompletion An optional function which will never be called. */ onSnapshot( onNext: (snapshot: QuerySnapshot<T>) => void, onError?: (error: Error) => void, onCompletion?: () => void, ): () => void; /** * Attaches a listener for `QuerySnapshot` events with snapshot listener options. * * NOTE: Although an onCompletion callback can be provided, it will never be called because the snapshot stream is never-ending. * * Returns an unsubscribe function to stop listening to events. * * #### Example * * ```js * const unsubscribe = firebase.firestore().collection('users') * .onSnapshot( * { includeMetadataChanges: true }, // SnapshotListenerOptions * (querySnapshot) => {}, // onNext * (error) => console.error(error), // onError * ); * * unsubscribe(); * ``` * @param options Options controlling the listen behavior. * @param onNext A callback to be called every time a new `QuerySnapshot` is available. * @param onError A callback to be called if the listen fails or is cancelled. No further callbacks will occur. * @param onCompletion An optional function which will never be called. */ onSnapshot( options: SnapshotListenOptions, onNext: (snapshot: QuerySnapshot<T>) => void, onError?: (error: Error) => void, onCompletion?: () => void, ): () => void; /** * Creates and returns a new Query that's additionally sorted by the specified field, optionally in descending order instead of ascending. * * * #### Example * * #### Example * * ```js * // Get users in order of age, descending * const querySnapshot = firebase.firestore() * .collection('users') * .orderBy('age', 'desc') * .get(); * ``` * * @param fieldPath The field to sort by. Either a string or FieldPath instance. * @param directionStr Optional direction to sort by (`asc` or `desc`). If not specified, order will be ascending. */ orderBy(fieldPath: keyof T | string | FieldPath, directionStr?: 'asc' | 'desc'): Query<T>; /** * Creates and returns a new Query that starts after the provided document (exclusive). The start * position is relative to the order of the query. The document must contain all of the fields * provided in the orderBy of this query. * * #### Example * * ```js * const user = await firebase.firestore().doc('users/alovelace').get(); * * // Get all users up to, but not including, a specific user in order of age * const querySnapshot = await firebase.firestore() * .collection('users') * .orderBy('age') * .startAfter(user) * .get(); * ``` * * > Cursor snapshot queries have limitations. Please see [Query limitations](/query-limitations) for more information. * * @param snapshot The snapshot of the document to start after. */ startAfter(snapshot: DocumentSnapshot<T>): Query<T>; /** * Creates and returns a new Query that starts after the provided fields relative to the order of * the query. The order of the field values must match the order of the order by clauses of the query. * * #### Example * * ```js * // Get all users who's age is above 30 * const querySnapshot = await firebase.firestore() * .collection('users') * .orderBy('age') * .startAfter(30) * .get(); * ``` * * @param fieldValues The field values to start this query after, in order of the query's order by. */ startAfter(...fieldValues: any[]): Query<T>; /** * Creates and returns a new Query that starts at the provided document (inclusive). The start * position is relative to the order of the query. The document must contain all of the * fields provided in the orderBy of this query. * * #### Example * * ```js * const user = await firebase.firestore().doc('users/alovelace').get(); * * // Get all users up to a specific user in order of age * const querySnapshot = await firebase.firestore() * .collection('users') * .orderBy('age') * .startAt(user) * .get(); * ``` * * > Cursor snapshot queries have limitations. Please see [Query limitations](/query-limitations) for more information. * * @param snapshot The snapshot of the document to start at. */ startAt(snapshot: DocumentSnapshot<T>): Query<T>; /** * Creates and returns a new Query that starts at the provided fields relative to the order of the query. * The order of the field values must match the order of the order by clauses of the query. * * #### Example * * ```js * // Get all users who's age is 30 or above * const querySnapshot = await firebase.firestore() * .collection('users') * .orderBy('age') * .startAt(30) * .get(); * ``` * * @param fieldValues The field values to start this query at, in order of the query's order by. */ startAt(...fieldValues: any[]): Query<T>; /** * Creates and returns a new Query with the additional filter that documents must contain the specified field and * the value should satisfy the relation constraint provided. * * #### Example * * ```js * // Get all users who's age is 30 or above * const querySnapshot = await firebase.firestore() * .collection('users') * .where('age', '>=', 30); * .get(); * ``` * * @param fieldPath The path to compare. * @param opStr The operation string (e.g "<", "<=", "==", ">", ">=", "!=", "array-contains", "array-contains-any", "in", "not-in"). * @param value The comparison value. */ where(fieldPath: keyof T | FieldPath, opStr: WhereFilterOp, value: any): Query<T>; /** * Creates and returns a new Query with the additional filter that documents must contain the specified field and * the value should satisfy the relation constraint provided. * * #### Example * * ```js * // Get all users who's age is 30 or above * const querySnapshot = await firebase.firestore() * .collection('users') * .where(Filter('age', '>=', 30)); * .get(); * ``` * * @param filter The filter to apply to the query. */ where(filter: QueryFilterConstraint): Query<T>; } /** * Filter conditions in a `Query.where()` clause are specified using the strings '<', '<=', '==', '>=', '>', 'array-contains', 'array-contains-any' or 'in'. */ export type WhereFilterOp = | '<' | '<=' | '==' | '>' | '>=' | '!=' | 'array-contains' | 'array-contains-any' | 'in' | 'not-in'; /** * A `QuerySnapshot` contains zero or more `QueryDocumentSnapshot` objects representing the results of a query. The documents * can be accessed as an array via the `docs` property or enumerated using the `forEach` method. The number of documents * can be determined via the `empty` and `size` properties. */ export interface QuerySnapshot<T extends DocumentData = DocumentData> { /** * An array of all the documents in the `QuerySnapshot`. */ docs: QueryDocumentSnapshot<T>[]; /** * True if there are no documents in the `QuerySnapshot`. */ empty: boolean; /** * Metadata about this snapshot, concerning its source and if it has local modifications. */ metadata: SnapshotMetadata; /** * The query on which you called get or `onSnapshot` in order to `get` this `QuerySnapshot`. */ query: Query<T>; /** * The number of documents in the `QuerySnapshot`. */ size: number; /** * Returns an array of the documents changes since the last snapshot. If this is the first snapshot, all documents * will be in the list as added changes. * * To include metadata changes, ensure that the `onSnapshot()` method includes metadata changes. * * #### Example * * ```js * firebase.firestore().collection('users') * .onSnapshot((querySnapshot) => { * console.log('Metadata Changes', querySnapshot.docChanges()); * }); * ``` * * #### Example - With metadata changes * * ```js * firebase.firestore().collection('users') * .onSnapshot({ includeMetadataChanges: true }, (querySnapshot) => { * console.log('Metadata Changes', querySnapshot.docChanges({ * includeMetadataChanges: true, * })); * }); * ``` * * @param options `SnapshotListenOptions` that control whether metadata-only changes (i.e. only `DocumentSnapshot.metadata` changed) should trigger snapshot events. */ docChanges(options?: SnapshotListenOptions): DocumentChange<T>[]; /** * Enumerates all of the documents in the