UNPKG

@google-cloud/firestore

Version:
1,226 lines (1,150 loc) 128 kB
/*! * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file 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. */ // We deliberately use `any` in the external API to not impose type-checking // on end users. /* eslint-disable @typescript-eslint/no-explicit-any */ // Declare a global (ambient) namespace // (used when not using import statement, but just script include). declare namespace FirebaseFirestore { /** Alias for `any` but used where a Firestore field value would be provided. */ export type DocumentFieldValue = any; /** * Document data (for use with `DocumentReference.set()`) consists of fields * mapped to values. */ export type DocumentData = {[field: string]: DocumentFieldValue}; /** * Similar to Typescript's `Partial<T>`, but allows nested fields to be * omitted and FieldValues to be passed in as property values. */ export type PartialWithFieldValue<T> = | Partial<T> | (T extends Primitive ? T : T extends {} ? { [K in keyof T]?: T[K] extends Function ? T[K] : PartialWithFieldValue<T[K]> | FieldValue; } : never); /** * Allows FieldValues to be passed in as a property value while maintaining * type safety. */ export type WithFieldValue<T> = | T | (T extends Primitive ? T : T extends {} ? { [K in keyof T]: T[K] extends Function ? T[K] : WithFieldValue<T[K]> | FieldValue; } : never); /** * Update data (for use with [update]{@link DocumentReference#update}) * that contains paths mapped to values. Fields that contain dots reference * nested fields within the document. FieldValues can be passed in * as property values. * * You can update a top-level field in your document by using the field name * as a key (e.g. `foo`). The provided value completely replaces the contents * for this field. * * You can also update a nested field directly by using its field path as a * key (e.g. `foo.bar`). This nested field update replaces the contents at * `bar` but does not modify other data under `foo`. */ export type UpdateData<T> = T extends Primitive ? T : T extends {} ? { // If `string extends K`, this is an index signature like // `{[key: string]: { foo: bool }}`. In the generated UpdateData // indexed properties can match their type or any child types. [K in keyof T]?: string extends K ? PartialWithFieldValue<ChildTypes<T[K]>> : UpdateData<T[K]> | FieldValue; } & NestedUpdateFields<T> : Partial<T>; /** * For the given type, return a union type of T * and the types of all child properties of T. */ export type ChildTypes<T> = T extends Record<string, unknown> ? | { [K in keyof T & string]: ChildTypes<T[K]>; }[keyof T & string] | T : T; /** Primitive types. */ export type Primitive = string | number | boolean | undefined | null; /** * For each field (e.g. 'bar'), find all nested keys (e.g. {'bar.baz': T1, * 'bar.qux': T2}). Intersect them together to make a single map containing * all possible keys that are all marked as optional */ export type NestedUpdateFields<T extends Record<string, unknown>> = UnionToIntersection< { // If `string extends K`, this is an index signature like // `{[key: string]: { foo: bool }}`. We map these properties to // `never`, which prevents prefixing a nested key with `[string]`. // We don't want to generate a field like `[string].foo: bool`. [K in keyof T & string]: string extends K ? never : ChildUpdateFields<K, T[K]>; }[keyof T & string] // Also include the generated prefix-string keys. >; /** * Helper for calculating the nested fields for a given type T1. This is needed * to distribute union types such as `undefined | {...}` (happens for optional * props) or `{a: A} | {b: B}`. * * In this use case, `V` is used to distribute the union types of `T[K]` on * `Record`, since `T[K]` is evaluated as an expression and not distributed. * * See https://www.typescriptlang.org/docs/handbook/advanced-types.html#distributive-conditional-types */ export type ChildUpdateFields<K extends string, V> = // Only allow nesting for map values V extends Record<string, unknown> ? // Recurse into the map and add the prefix in front of each key // (for example prefix 'bar.' to create: 'bar.baz' and 'bar.qux'). AddPrefixToKeys<K, UpdateData<V>> : // UpdateData is always a map of values. never; /** * Returns a new map where every key is prefixed with the outer key appended * to a dot. */ export type AddPrefixToKeys< Prefix extends string, T extends Record<string, unknown>, > = // Remap K => Prefix.K. See https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#key-remapping-via-as // `string extends K : ...` is used to detect index signatures // like `{[key: string]: bool}`. We map these properties to type `any` // because a field path like `foo.[string]` will match `foo.bar` or a // sub-path `foo.bar.baz`. Because it matches a sub-path, we have to // make this type a union to including all types of the sub-path properties. // This is a significant downside to using index signatures in types for `T` // for `UpdateData<T>`. { [K in keyof T & string as `${Prefix}.${K}`]+?: string extends K ? ChildTypes<T[K]> : T[K]; }; /** * Given a union type `U = T1 | T2 | ...`, returns an intersected type * `(T1 & T2 & ...)`. * * Uses distributive conditional types and inference from conditional types. * This works because multiple candidates for the same type variable in * contra-variant positions causes an intersection type to be inferred. * https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-inference-in-conditional-types * https://stackoverflow.com/questions/50374908/transform-union-type-to-intersection-type */ export type UnionToIntersection<U> = ( U extends unknown ? (k: U) => void : never ) extends (k: infer I) => void ? I : never; /** * Sets or disables the log function for all active Firestore instances. * * @param logger A log function that takes a message (such as `console.log`) or * `null` to turn off logging. */ function setLogFunction(logger: ((msg: string) => void) | null): void; /** * Converter used by `withConverter()` to transform user objects of type * `AppModelType` into Firestore data of type `DbModelType`. * * Using the converter allows you to specify generic type arguments when * storing and retrieving objects from Firestore. * * In this context, an "AppModel" is a class that is used in an application to * package together related information and functionality. Such a class could, * for example, have properties with complex, nested data types, properties * used for memoization, properties of types not supported by Firestore (such * as `symbol` and `bigint`), and helper functions that perform compound * operations. Such classes are not suitable and/or possible to store into a * Firestore database. Instead, instances of such classes need to be converted * to "plain old JavaScript objects" (POJOs) with exclusively primitive * properties, potentially nested inside other POJOs or arrays of POJOs. In * this context, this type is referred to as the "DbModel" and would be an * object suitable for persisting into Firestore. For convenience, * applications can implement `FirestoreDataConverter` and register the * converter with Firestore objects, such as `DocumentReference` or `Query`, * to automatically convert `AppModel` to `DbModel` when storing into * Firestore, and convert `DbModel` to `AppModel` when retrieving from * Firestore. * * @example * * Simple Example * * const numberConverter = { * toFirestore(value: WithFieldValue<number>) { * return { value }; * }, * fromFirestore(snapshot: QueryDocumentSnapshot) { * return snapshot.data().value as number; * } * }; * * async function simpleDemo(db: Firestore): Promise<void> { * const documentRef = db.doc('values/value123').withConverter(numberConverter); * * // converters are used with `setDoc`, `addDoc`, and `getDoc` * await documentRef.set(42); * const snapshot1 = await documentRef.get(); * assertEqual(snapshot1.data(), 42); * * // converters are not used when writing data with `updateDoc` * await documentRef.update({ value: 999 }); * const snapshot2 = await documentRef.get(); * assertEqual(snapshot2.data(), 999); * } * * Advanced Example * * // The Post class is a model that is used by our application. * // This class may have properties and methods that are specific * // to our application execution, which do not need to be persisted * // to Firestore. * class Post { * constructor( * readonly title: string, * readonly author: string, * readonly lastUpdatedMillis: number * ) {} * toString(): string { * return `${this.title} by ${this.author}`; * } * } * * // The PostDbModel represents how we want our posts to be stored * // in Firestore. This DbModel has different properties (`ttl`, * // `aut`, and `lut`) from the Post class we use in our application. * interface PostDbModel { * ttl: string; * aut: { firstName: string; lastName: string }; * lut: Timestamp; * } * * // The `PostConverter` implements `FirestoreDataConverter` and specifies * // how the Firestore SDK can convert `Post` objects to `PostDbModel` * // objects and vice versa. * class PostConverter implements FirestoreDataConverter<Post, PostDbModel> { * toFirestore(post: WithFieldValue<Post>): WithFieldValue<PostDbModel> { * return { * ttl: post.title, * aut: this._autFromAuthor(post.author), * lut: this._lutFromLastUpdatedMillis(post.lastUpdatedMillis) * }; * } * * fromFirestore(snapshot: QueryDocumentSnapshot): Post { * const data = snapshot.data() as PostDbModel; * const author = `${data.aut.firstName} ${data.aut.lastName}`; * return new Post(data.ttl, author, data.lut.toMillis()); * } * * _autFromAuthor( * author: string | FieldValue * ): { firstName: string; lastName: string } | FieldValue { * if (typeof author !== 'string') { * // `author` is a FieldValue, so just return it. * return author; * } * const [firstName, lastName] = author.split(' '); * return {firstName, lastName}; * } * * _lutFromLastUpdatedMillis( * lastUpdatedMillis: number | FieldValue * ): Timestamp | FieldValue { * if (typeof lastUpdatedMillis !== 'number') { * // `lastUpdatedMillis` must be a FieldValue, so just return it. * return lastUpdatedMillis; * } * return Timestamp.fromMillis(lastUpdatedMillis); * } * } * * async function advancedDemo(db: Firestore): Promise<void> { * // Create a `DocumentReference` with a `FirestoreDataConverter`. * const documentRef = db.doc('posts/post123').withConverter(new PostConverter()); * * // The `data` argument specified to `DocumentReference.set()` is type * // checked by the TypeScript compiler to be compatible with `Post`. Since * // the `data` argument is typed as `WithFieldValue<Post>` rather than just * // `Post`, this allows properties of the `data` argument to also be special * // Firestore values that perform server-side mutations, such as * // `FieldValue.arrayRemove()`, `FieldValue.delete()`, and * // `FieldValue.serverTimestamp()`. * await documentRef.set({ * title: 'My Life', * author: 'Foo Bar', * lastUpdatedMillis: FieldValue.serverTimestamp() * }); * * // The TypeScript compiler will fail to compile if the `data` argument * // to `DocumentReference.set()` is _not_ compatible with * // `WithFieldValue<Post>`. This type checking prevents the caller from * // specifying objects with incorrect properties or property values. * // @ts-expect-error "Argument of type { ttl: string; } is not assignable * // to parameter of type WithFieldValue<Post>" * await documentRef.set(documentRef, { ttl: 'The Title' }); * * // When retrieving a document with `DocumentReference.get()` the * // `DocumentSnapshot` object's `data()` method returns a `Post`, rather * // than a generic object, which would have been returned if the * // `DocumentReference` did _not_ have a `FirestoreDataConverter` * // attached to it. * const snapshot1: DocumentSnapshot<Post> = await documentRef.get(); * const post1: Post = snapshot1.data()!; * if (post1) { * assertEqual(post1.title, 'My Life'); * assertEqual(post1.author, 'Foo Bar'); * } * * // The `data` argument specified to `DocumentReference.update()` is type * // checked by the TypeScript compiler to be compatible with * // `PostDbModel`. Note that unlike `DocumentReference.set()`, whose * // `data` argument must be compatible with `Post`, the `data` argument * // to `update()` must be compatible with `PostDbModel`. Similar to * // `set()`, since the `data` argument is typed as * // `WithFieldValue<PostDbModel>` rather than just `PostDbModel`, this * // allows properties of the `data` argument to also be those special * // Firestore values, like `FieldValue.arrayRemove()`, * // `FieldValue.delete()`, and `FieldValue.serverTimestamp()`. * await documentRef.update({ * 'aut.firstName': 'NewFirstName', * lut: FieldValue.serverTimestamp() * }); * * // The TypeScript compiler will fail to compile if the `data` argument * // to `DocumentReference.update()` is _not_ compatible with * // `WithFieldValue<PostDbModel>`. This type checking prevents the caller * // from specifying objects with incorrect properties or property values. * // @ts-expect-error "Argument of type { title: string; } is not * // assignable to parameter of type WithFieldValue<PostDbModel>" * await documentRef.update({ title: 'New Title' }); * const snapshot2: DocumentSnapshot<Post> = await documentRef.get(); * const post2: Post = snapshot2.data()!; * if (post2) { * assertEqual(post2.title, 'My Life'); * assertEqual(post2.author, 'NewFirstName Bar'); * } * } */ export interface FirestoreDataConverter< AppModelType, DbModelType extends DocumentData = DocumentData, > { /** * Called by the Firestore SDK to convert a custom model object of type * `AppModelType` into a plain Javascript object (suitable for writing * directly to the Firestore database) of type `DbModelType`. * * To use set() with `merge` and `mergeFields`, * toFirestore() must be defined with `Partial<T>`. * * The `WithFieldValue<T>` type extends `T` to also allow FieldValues such * as `FieldValue.delete()` to be used as property values. */ toFirestore( modelObject: WithFieldValue<AppModelType>, ): WithFieldValue<DbModelType>; /** * Called by the Firestore SDK to convert a custom model object of type * `AppModelType` into a plain Javascript object (suitable for writing * directly to the Firestore database) of type `DbModelType`. * * To use set() with `merge` and `mergeFields`, * toFirestore() must be defined with `Partial<T>`. * * The `PartialWithFieldValue<T>` type extends `Partial<T>` to allow * FieldValues such as `FieldValue.delete()` to be used as property values. * It also supports nested `Partial` by allowing nested fields to be * omitted. */ toFirestore( modelObject: PartialWithFieldValue<AppModelType>, options: SetOptions, ): PartialWithFieldValue<DbModelType>; /** * Called by the Firestore SDK to convert Firestore data into an object of * type `AppModelType`. You can access your data by calling: * `snapshot.data()`. * * Generally, the data returned from `snapshot.data()` can be cast to * `DbModelType`; however, this is not guaranteed because Firestore does not * enforce a schema on the database. For example, writes from a previous * version of the application or writes from another client that did not use * a type converter could have written data with different properties and/or * property types. The implementation will need to choose whether to * gracefully recover from non-conforming data or throw an error. */ fromFirestore(snapshot: QueryDocumentSnapshot): AppModelType; } /** * Settings used to directly configure a `Firestore` instance. */ export interface Settings { /** * The project ID from the Google Developer's Console, e.g. * 'grape-spaceship-123'. We will also check the environment variable * GCLOUD_PROJECT for your project ID. Can be omitted in environments that * support {@link https://cloud.google.com/docs/authentication Application * Default Credentials} */ projectId?: string; /** * The database name. If omitted, the default database will be used. */ databaseId?: string; /** The hostname to connect to. */ host?: string; /** The port to connect to. */ port?: number; /** * Local file containing the Service Account credentials as downloaded from * the Google Developers Console. Can be omitted in environments that * support {@link https://cloud.google.com/docs/authentication Application * Default Credentials}. To configure Firestore with custom credentials, use * the `credentials` property to provide the `client_email` and * `private_key` of your service account. */ keyFilename?: string; /** * The 'client_email' and 'private_key' properties of the service account * to use with your Firestore project. Can be omitted in environments that * support {@link https://cloud.google.com/docs/authentication Application * Default Credentials}. If your credentials are stored in a JSON file, you * can specify a `keyFilename` instead. */ credentials?: {client_email?: string; private_key?: string}; /** Whether to use SSL when connecting. */ ssl?: boolean; /** * The maximum number of idle GRPC channels to keep. A smaller number of idle * channels reduces memory usage but increases request latency for clients * with fluctuating request rates. If set to 0, shuts down all GRPC channels * when the client becomes idle. Defaults to 1. */ maxIdleChannels?: number; /** * Whether to use `BigInt` for integer types when deserializing Firestore * Documents. Regardless of magnitude, all integer values are returned as * `BigInt` to match the precision of the Firestore backend. Floating point * numbers continue to use JavaScript's `number` type. */ useBigInt?: boolean; /** * Whether to skip nested properties that are set to `undefined` during * object serialization. If set to `true`, these properties are skipped * and not written to Firestore. If set `false` or omitted, the SDK throws * an exception when it encounters properties of type `undefined`. */ ignoreUndefinedProperties?: boolean; /** * Whether to force the use of HTTP/1.1 REST transport until a method that requires gRPC * is called. When a method requires gRPC, this Firestore client will load dependent gRPC * libraries and then use gRPC transport for communication from that point forward. * Currently the only operation that requires gRPC is creating a snapshot listener with * the method `DocumentReference<T>.onSnapshot()`, `CollectionReference<T>.onSnapshot()`, * or `Query<T>.onSnapshot()`. */ preferRest?: boolean; /** * Settings related to telemetry collection by this client. * @beta */ openTelemetry?: FirestoreOpenTelemetryOptions; [key: string]: any; // Accept other properties, such as GRPC settings. } /** * Options to configure telemetry collection. * This is a 'beta' interface and may change in backwards incompatible ways. * @beta */ export interface FirestoreOpenTelemetryOptions { /** * The OpenTelemetry TracerProvider instance that the SDK should use to * create trace spans. If not provided, the SDK will use the Global TracerProvider. * * Even if a Global TracerProvider has been registered, users can still * disable this client's span creation by passing in a "no-op" tracer provider * here, or by setting the `FIRESTORE_ENABLE_TRACING` environment variable to `OFF` or `FALSE`. */ tracerProvider?: any; } /** Options to configure a read-only transaction. */ export interface ReadOnlyTransactionOptions { /** Set to true to indicate a read-only transaction. */ readOnly: true; /** * If specified, documents are read at the given time. This may not be more * than 60 seconds in the past from when the request is processed by the * server. */ readTime?: Timestamp; } /** Options to configure a read-write transaction. */ export interface ReadWriteTransactionOptions { /** Set to false or omit to indicate a read-write transaction. */ readOnly?: false; /** * The maximum number of attempts for this transaction. Defaults to 5. */ maxAttempts?: number; } /** * `Firestore` represents a Firestore Database and is the entry point for all * Firestore operations. */ export class Firestore { /** * @param settings Configuration object. See [Firestore Documentation] * {@link https://firebase.google.com/docs/firestore/} */ public constructor(settings?: Settings); /** * Specifies custom settings to be used to configure the `Firestore` * instance. Can only be invoked once and before any other Firestore * method. * * If settings are provided via both `settings()` and the `Firestore` * constructor, both settings objects are merged and any settings provided * via `settings()` take precedence. * * @param {object} settings The settings to use for all Firestore * operations. */ settings(settings: Settings): void; /** * Returns the Database ID for this Firestore instance. */ get databaseId(): string; /** * Gets a `CollectionReference` instance that refers to the collection at * the specified path. * * @param collectionPath A slash-separated path to a collection. * @return The `CollectionReference` instance. */ collection(collectionPath: string): CollectionReference; /** * Gets a `DocumentReference` instance that refers to the document at the * specified path. * * @param documentPath A slash-separated path to a document. * @return The `DocumentReference` instance. */ doc(documentPath: string): DocumentReference; /** * Creates and returns a new Query that includes all documents in the * database that are contained in a collection or subcollection with the * given collectionId. * * @param collectionId Identifies the collections to query over. Every * collection or subcollection with this ID as the last segment of its path * will be included. Cannot contain a slash. * @return The created `CollectionGroup`. */ collectionGroup(collectionId: string): CollectionGroup; /** * Retrieves multiple documents from Firestore. * * The first argument is required and must be of type `DocumentReference` * followed by any additional `DocumentReference` documents. If used, the * optional `ReadOptions` must be the last argument. * * @param {Array.<DocumentReference|ReadOptions>} documentRefsOrReadOptions * The `DocumentReferences` to receive, followed by an optional field * mask. * @return A Promise that resolves with an array of resulting document * snapshots. */ getAll( ...documentRefsOrReadOptions: Array<DocumentReference | ReadOptions> ): Promise<Array<DocumentSnapshot>>; /** * Recursively deletes all documents and subcollections at and under the * specified level. * * If any delete fails, the promise is rejected with an error message * containing the number of failed deletes and the stack trace of the last * failed delete. The provided reference is deleted regardless of whether * all deletes succeeded. * * `recursiveDelete()` uses a BulkWriter instance with default settings to * perform the deletes. To customize throttling rates or add success/error * callbacks, pass in a custom BulkWriter instance. * * @param ref The reference of a document or collection to delete. * @param bulkWriter A custom BulkWriter instance used to perform the * deletes. * @return A promise that resolves when all deletes have been performed. * The promise is rejected if any of the deletes fail. * * @example * // Recursively delete a reference and log the references of failures. * const bulkWriter = firestore.bulkWriter(); * bulkWriter * .onWriteError((error) => { * if ( * error.failedAttempts < MAX_RETRY_ATTEMPTS * ) { * return true; * } else { * console.log('Failed write at document: ', error.documentRef.path); * return false; * } * }); * await firestore.recursiveDelete(docRef, bulkWriter); */ recursiveDelete( ref: CollectionReference<any, any> | DocumentReference<any, any>, bulkWriter?: BulkWriter, ): Promise<void>; /** * Terminates the Firestore client and closes all open streams. * * @return A Promise that resolves when the client is terminated. */ terminate(): Promise<void>; /** * Fetches the root collections that are associated with this Firestore * database. * * @returns A Promise that resolves with an array of CollectionReferences. */ listCollections(): Promise<Array<CollectionReference>>; /** * Executes the given updateFunction and commits the changes applied within * the transaction. * * You can use the transaction object passed to 'updateFunction' to read and * modify Firestore documents under lock. You have to perform all reads * before you perform any write. * * Transactions can be performed as read-only or read-write transactions. By * default, transactions are executed in read-write mode. * * A read-write transaction obtains a pessimistic lock on all documents that * are read during the transaction. These locks block other transactions, * batched writes, and other non-transactional writes from changing that * document. Any writes in a read-write transactions are committed once * 'updateFunction' resolves, which also releases all locks. * * If a read-write transaction fails with contention, the transaction is * retried up to five times. The `updateFunction` is invoked once for each * attempt. * * Read-only transactions do not lock documents. They can be used to read * documents at a consistent snapshot in time, which may be up to 60 seconds * in the past. Read-only transactions are not retried. * * Transactions time out after 60 seconds if no documents are read. * Transactions that are not committed within than 270 seconds are also * aborted. Any remaining locks are released when a transaction times out. * * @param updateFunction The function to execute within the transaction * context. * @param transactionOptions Transaction options. * @return If the transaction completed successfully or was explicitly * aborted (by the updateFunction returning a failed Promise), the Promise * returned by the updateFunction will be returned here. Else if the * transaction failed, a rejected Promise with the corresponding failure * error will be returned. */ runTransaction<T>( updateFunction: (transaction: Transaction) => Promise<T>, transactionOptions?: | ReadWriteTransactionOptions | ReadOnlyTransactionOptions, ): Promise<T>; /** * Creates a write batch, used for performing multiple writes as a single * atomic operation. */ batch(): WriteBatch; /** * Creates a [BulkWriter]{@link BulkWriter}, used for performing * multiple writes in parallel. Gradually ramps up writes as specified * by the 500/50/5 rule. * * @see https://firebase.google.com/docs/firestore/best-practices#ramping_up_traffic * * @param options An options object used to configure the throttling * behavior for the underlying BulkWriter. */ bulkWriter(options?: BulkWriterOptions): BulkWriter; /** * Creates a new `BundleBuilder` instance to package selected Firestore data into * a bundle. * * @param bundleId The ID of the bundle. When loaded on clients, client SDKs use this ID * and the timestamp associated with the bundle to tell if it has been loaded already. * If not specified, a random identifier will be used. * * * @example * const bundle = firestore.bundle('data-bundle'); * const docSnapshot = await firestore.doc('abc/123').get(); * const querySnapshot = await firestore.collection('coll').get(); * * const bundleBuffer = bundle.add(docSnapshot); // Add a document * .add('coll-query', querySnapshot) // Add a named query. * .build() * // Save `bundleBuffer` to CDN or stream it to clients. */ bundle(bundleId?: string): BundleBuilder; } /** * 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. * @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); readonly latitude: number; readonly longitude: number; /** * Returns true if this `GeoPoint` is equal to the provided one. * * @param other The `GeoPoint` to compare against. * @return true if this `GeoPoint` is equal to the provided one. */ isEqual(other: GeoPoint): boolean; } /** * A reference to a transaction. * The `Transaction` object passed to a transaction's updateFunction provides * the methods to read and write data within the transaction context. See * `Firestore.runTransaction()`. */ export class Transaction { private constructor(); /** * Retrieves a query result. Holds a pessimistic lock on all returned * documents. * * @param query A query to execute. * @return A QuerySnapshot for the retrieved data. */ get<AppModelType, DbModelType extends DocumentData>( query: Query<AppModelType, DbModelType>, ): Promise<QuerySnapshot<AppModelType, DbModelType>>; /** * Reads the document referenced by the provided `DocumentReference.` * Holds a pessimistic lock on the returned document. * * @param documentRef A reference to the document to be read. * @return A DocumentSnapshot for the read data. */ get<AppModelType, DbModelType extends DocumentData>( documentRef: DocumentReference<AppModelType, DbModelType>, ): Promise<DocumentSnapshot<AppModelType, DbModelType>>; /** * Retrieves an aggregate query result. Holds a pessimistic lock on all * documents that were matched by the underlying query. * * @param aggregateQuery An aggregate query to execute. * @return An AggregateQuerySnapshot for the retrieved data. */ get< AppModelType, DbModelType extends DocumentData, AggregateSpecType extends AggregateSpec, >( aggregateQuery: AggregateQuery< AggregateSpecType, AppModelType, DbModelType >, ): Promise< AggregateQuerySnapshot<AggregateSpecType, AppModelType, DbModelType> >; /** * Retrieves multiple documents from Firestore. Holds a pessimistic lock on * all returned documents. * * The first argument is required and must be of type `DocumentReference` * followed by any additional `DocumentReference` documents. If used, the * optional `ReadOptions` must be the last argument. * * @param {Array.<DocumentReference|ReadOptions>} documentRefsOrReadOptions * The `DocumentReferences` to receive, followed by an optional field * mask. * @return A Promise that resolves with an array of resulting document * snapshots. */ getAll<AppModelType, DbModelType extends DocumentData>( ...documentRefsOrReadOptions: Array< DocumentReference<AppModelType, DbModelType> | ReadOptions > ): Promise<Array<DocumentSnapshot<AppModelType, DbModelType>>>; /** * Create the document referred to by the provided `DocumentReference`. * The operation will fail the transaction if a document exists at the * specified location. * * @param documentRef A reference to the document to be create. * @param data The object data to serialize as the document. * @throws Error If the provided input is not a valid Firestore document. * @return This `Transaction` instance. Used for chaining method calls. */ create<AppModelType, DbModelType extends DocumentData>( documentRef: DocumentReference<AppModelType, DbModelType>, data: WithFieldValue<AppModelType>, ): Transaction; /** * Writes to the document referred to by the provided `DocumentReference`. * If the document does not exist yet, it will be created. If you pass * `SetOptions`, the provided data can be merged into the existing document. * * @param documentRef A reference to the document to be set. * @param data An object of the fields and values for the document. * @param options An object to configure the set behavior. * @param options.merge - If true, set() merges the values specified in its * data argument. Fields omitted from this set() call remain untouched. If * your input sets any field to an empty map, all nested fields are * overwritten. * @param options.mergeFields - If provided, set() only replaces the * specified field paths. Any field path that is not specified is ignored * and remains untouched. If your input sets any field to an empty map, all * nested fields are overwritten. * @throws Error If the provided input is not a valid Firestore document. * @return This `Transaction` instance. Used for chaining method calls. */ set<AppModelType, DbModelType extends DocumentData>( documentRef: DocumentReference<AppModelType, DbModelType>, data: PartialWithFieldValue<AppModelType>, options: SetOptions, ): Transaction; set<AppModelType, DbModelType extends DocumentData>( documentRef: DocumentReference<AppModelType, DbModelType>, data: WithFieldValue<AppModelType>, ): Transaction; /** * Updates fields in the document referred to by the provided * `DocumentReference`. The update will fail if applied to a document that * does not exist. * * Nested fields can be updated by providing dot-separated field path * strings. * * @param documentRef A reference to the document to be updated. * @param data An object containing the fields and values with which to * update the document. * @param precondition A Precondition to enforce on this update. * @throws Error If the provided input is not valid Firestore data. * @return This `Transaction` instance. Used for chaining method calls. */ update<AppModelType, DbModelType extends DocumentData>( documentRef: DocumentReference<AppModelType, DbModelType>, data: UpdateData<DbModelType>, precondition?: Precondition, ): Transaction; /** * Updates fields in the document referred to by the provided * `DocumentReference`. The update will fail if applied to a document that * does not exist. * * Nested fields can be updated by providing dot-separated field path * strings or by providing FieldPath objects. * * A `Precondition` restricting this update can be specified as the last * argument. * * @param documentRef A reference to the document to be updated. * @param field The first field to update. * @param value The first value * @param fieldsOrPrecondition An alternating list of field paths and values * to update, optionally followed by a `Precondition` to enforce on this * update. * @throws Error If the provided input is not valid Firestore data. * @return This `Transaction` instance. Used for chaining method calls. */ update( documentRef: DocumentReference<any, any>, field: string | FieldPath, value: any, ...fieldsOrPrecondition: any[] ): Transaction; /** * Deletes the document referred to by the provided `DocumentReference`. * * @param documentRef A reference to the document to be deleted. * @param precondition A Precondition to enforce for this delete. * @return This `Transaction` instance. Used for chaining method calls. */ delete( documentRef: DocumentReference<any, any>, precondition?: Precondition, ): Transaction; } /** * A Firestore BulkWriter than can be used to perform a large number of writes * in parallel. Writes to the same document will be executed sequentially. * * @class */ export class BulkWriter { private constructor(); /** * Create a document with the provided data. This single operation will fail * if a document exists at its location. * * @param documentRef A reference to the document to be * created. * @param data The object to serialize as the document. * @throws Error If the provided input is not a valid Firestore document. * @returns A promise that resolves with the result of the write. If the * write fails, the promise is rejected with a * [BulkWriterError]{@link BulkWriterError}. */ create<AppModelType, DbModelType extends DocumentData>( documentRef: DocumentReference<AppModelType, DbModelType>, data: WithFieldValue<AppModelType>, ): Promise<WriteResult>; /** * Delete a document from the database. * * @param documentRef A reference to the document to be * deleted. * @param precondition A precondition to enforce for this * delete. * @param precondition.lastUpdateTime If set, enforces that the * document was last updated at lastUpdateTime. Fails the batch if the * document doesn't exist or was last updated at a different time. * @param precondition.exists If set, enforces that the target document * must or must not exist. * @returns A promise that resolves with the result of the delete. If the * delete fails, the promise is rejected with a * [BulkWriterError]{@link BulkWriterError}. */ delete( documentRef: DocumentReference<any, any>, precondition?: Precondition, ): Promise<WriteResult>; /** * Write to the document referred to by the provided * [DocumentReference]{@link DocumentReference}. If the document does not * exist yet, it will be created. If you pass * [SetOptions]{@link SetOptions}., the provided data can be merged into the * existing document. * * @param documentRef A reference to the document to be * set. * @param data The object to serialize as the document. * @param options An object to configure the set behavior. * @param options.merge - If true, set() merges the values specified in its * data argument. Fields omitted from this set() call remain untouched. If * your input sets any field to an empty map, all nested fields are * overwritten. * @param options.mergeFields - If provided, set() only replaces the * specified field paths. Any field path that is not specified is ignored * and remains untouched. If your input sets any field to an empty map, all * nested fields are overwritten. * @throws Error If the provided input is not a valid Firestore document. * @returns A promise that resolves with the result of the write. If the * write fails, the promise is rejected with a * [BulkWriterError]{@link BulkWriterError}. */ set<AppModelType, DbModelType extends DocumentData>( documentRef: DocumentReference<AppModelType, DbModelType>, data: PartialWithFieldValue<AppModelType>, options: SetOptions, ): Promise<WriteResult>; set<AppModelType, DbModelType extends DocumentData>( documentRef: DocumentReference<AppModelType, DbModelType>, data: WithFieldValue<AppModelType>, ): Promise<WriteResult>; /** * Update fields of the document referred to by the provided * [DocumentReference]{@link DocumentReference}. If the document doesn't yet * exist, the update fails and the entire batch will be rejected. * * The update() method accepts either an object with field paths encoded as * keys and field values encoded as values, or a variable number of * arguments that alternate between field paths and field values. Nested * fields can be updated by providing dot-separated field path strings or by * providing FieldPath objects. * * * A Precondition restricting this update can be specified as the last * argument. * * @param documentRef A reference to the document to be updated. * @param data An object containing the fields and values with which to * update the document. * @param precondition A Precondition to enforce on this update. * @throws Error If the provided input is not valid Firestore data. * @returns A promise that resolves with the result of the write. If the * write fails, the promise is rejected with a * [BulkWriterError]{@link BulkWriterError}. */ update<AppModelType, DbModelType extends DocumentData>( documentRef: DocumentReference<AppModelType, DbModelType>, data: UpdateData<DbModelType>, precondition?: Precondition, ): Promise<WriteResult>; /** * Update fields of the document referred to by the provided * [DocumentReference]{@link DocumentReference}. If the document doesn't yet * exist, the update fails and the entire batch will be rejected. * * The update() method accepts either an object with field paths encoded as * keys and field values encoded as values, or a variable number of * arguments that alternate between field paths and field values. Nested * fields can be updated by providing dot-separated field path strings or by * providing FieldPath objects. * * * A Precondition restricting this update can be specified as the last * argument. * * @param documentRef A reference to the document to be updated. * @param field The first field to update. * @param value The first value * @param fieldsOrPrecondition An alternating list of field paths and values * to update, optionally followed a `Precondition` to enforce on this * update. * @throws Error If the provided input is not valid Firestore data; * @returns A promise that resolves with the result of the write. If the * write fails, the promise is rejected with a * [BulkWriterError]{@link BulkWriterError}. */ update( documentRef: DocumentReference<any, any>, field: string | FieldPath, value: any, ...fieldsOrPrecondition: any[] ): Promise<WriteResult>; /** * Attaches a listener that is run every time a BulkWriter operation * successfully completes. * * @param callback A callback to be called every time a BulkWriter operation * successfully completes. */ onWriteResult( callback: ( documentRef: DocumentReference<any, any>, result: WriteResult, ) => void, ): void; /** * Attaches an error handler listener that is run every time a BulkWriter * operation fails. * * BulkWriter has a default error handler that retries UNAVAILABLE and * ABORTED errors up to a maximum of 10 failed attempts. When an error * handler is specified, the default error handler will be overwritten. * * @param shouldRetryCallback A callback to be called every time a BulkWriter * operation fails. Returning `true` will retry the operation. Returning * `false` will stop the retry loop. */ onWriteError( shouldRetryCallback: (error: BulkWriterError) => boolean, ): void; /** * Commits all writes that have been enqueued up to this point in parallel. * * Returns a Promise that resolves when all currently queued operations have * been committed. The Promise will never be rejected since the results for * each individual operation are conveyed via their individual Promises. * * The Promise resolves immediately if there are no pending writes. * Otherwise, the Promise waits for all previously issued writes, but it * does not wait for writes that were added after the method is called. If * you want to wait for additional writes, call `flush()` again. * * @return A promise that resolves when all enqueued writes * up to this point have been committed. */ flush(): Promise<void>; /** * Commits all enqueued writes and marks the BulkWriter instance as closed. * * After calling `close()`, calling any method will throw an error. Any * retries scheduled as part of an `onWriteError()` handler will be run * before the `close()` promise resolves. * * Returns a Promise that resolves when all writes have been committed. The * Promise will never be rejected. Calling this method will send all * requests. The promise resolves immediately if there are no pending * writes. * * @return A promise that resolves when all enqueued writes * up to this point have been committed. */ close(): Promise<void>; } /** * An options object to configure throttling on BulkWriter. */ export interface BulkWriterOptions { /** * Whether to disable or configure throttling. By default, throttling is * enabled. This field can be set to either a boolean or a config * object. Setting it to `true` will use default values. You can override * the defaults by setting it to `false` to disable throttling, or by * setting the config values to enable throttling with the provided values. * * @see https://firebase.google.com/docs/firestore/best-practices#ramping_up_traffic * * @param initialOpsPerSecond The initial maximum number of operations per * second allowed by the throttler. If this field is not set, the default * is 500 operations per second. * @param maxOpsPerSecond The maximum number of operations per second * allowed by the throttler. If this field is set, the throttler's allowed * operations per second does not ramp up past the specified operations per * second. */ readonly throttling?: | boolean | {initialOpsPerSecond?: number; maxOpsPerSecond?: number}; } /** * The error thrown when a BulkWriter operation fails. */ export class BulkWriterError extends Error { /** The status code of the error. */ readonly code: GrpcStatus; /** The error message of the error. */ readonly message: string; /** The document reference the operation wa