/* * Copyright (c) 2016-present Invertase Limited & Contributors * * 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. * */ import type { CollectionReference, DocumentData, DocumentReference, DocumentSnapshot, Firestore, FirestoreSettings, LoadBundleTask, LoadBundleTaskProgress, LogLevel, Primitive, Query, QuerySnapshot, SetOptions, SnapshotOptions, Transaction, Unsubscribe, WriteBatch, WithFieldValue, AggregateType, PartialWithFieldValue, ListenSource, } from './firestore'; import type { PersistentCacheIndexManager } from '../FirestorePersistentCacheIndexManager'; import type { QueryConstraint } from '../modular/query'; import type { _Filter } from '../FirestoreFilter'; import type { Timestamp } from '../FirestoreTimestamp'; import { Blob } from '../FirestoreBlob'; /** Reserved optional trailing argument on legacy internal method signatures. */ export type FirestoreModularDeprecationArg = string; /** Query type passed to native ('collection' or 'collectionGroup'). */ export type FirestoreQueryTypeInternal = 'collection' | 'collectionGroup'; /** App instance with firestore() method (e.g. from getApp() when used for getFirestore()). */ export interface AppWithFirestoreInternal { firestore(databaseId?: string): Firestore; } /** Single filter spec passed to native (fieldPath serialized as string[] from QueryModifiers). */ export interface FirestoreFilterSpecInternal { fieldPath?: string[] | unknown; operator: string; value?: unknown; /** Nested queries for composite filters (AND/OR). */ queries?: FirestoreFilterSpecInternal[]; } /** Order spec passed to native (fieldPath serialized as string[] from QueryModifiers). */ export interface FirestoreOrderSpecInternal { fieldPath: string[] | unknown; direction: string; } /** Query options passed to native (limit, limitToLast, startAt, etc.). */ export interface FirestoreQueryOptionsInternal { limit?: number; limitToLast?: number; startAt?: unknown[]; startAfter?: unknown[]; endAt?: unknown[]; endBefore?: unknown[]; } /** Cursor field values (startAt, startAfter, endAt, endBefore) – serialized array passed to native. */ export type FirestoreCursorFieldsInternal = unknown[]; /** Single aggregate query spec passed to native (aggregateQuery). */ export interface FirestoreAggregateQuerySpecInternal { aggregateType: AggregateType; field: string | null; key: string; } /** Aggregate query result from native (passed to AggregateQuerySnapshot constructor). */ export interface FirestoreAggregateQueryResultInternal { count?: number; [key: string]: unknown; } /** Serialized expression node passed to native pipeline execute bridge. */ export interface FirestorePipelineFieldExpressionInternal { __kind?: 'expression'; exprType: 'Field'; path: string; } /** Serialized constant expression node passed to native pipeline execute bridge. */ export interface FirestorePipelineConstantExpressionInternal { __kind?: 'expression'; exprType: 'Constant'; value: FirestorePipelineSerializedValueInternal; } /** Serialized variable expression node passed to native pipeline execute bridge. */ export interface FirestorePipelineVariableExpressionInternal { __kind?: 'expression'; exprType: 'Variable'; name: string; } /** Serialized function expression node passed to native pipeline execute bridge. */ export interface FirestorePipelineFunctionExpressionInternal { __kind?: 'expression'; exprType?: 'Function'; name: string; args?: FirestorePipelineSerializedValueInternal[]; } /** Serialized aggregate function node passed to native pipeline execute bridge. */ export interface FirestorePipelineAggregateFunctionInternal { __kind?: 'aggregate'; exprType?: 'AggregateFunction'; kind: string; args?: FirestorePipelineSerializedValueInternal[]; } /** Serialized ordering node passed to native pipeline execute bridge. */ export interface FirestorePipelineOrderingInternal { __kind?: 'ordering'; expr: FirestorePipelineExpressionInternal; direction: 'ascending' | 'descending'; } /** Flat aliased field shape used to avoid nested field parsing on native platforms. */ export interface FirestorePipelineFlatAliasedFieldInternal { path: string; alias: string; as: string; } /** Serialized aliased expression node passed to native pipeline execute bridge. */ export interface FirestorePipelineAliasedExpressionInternal { __kind?: 'aliasedExpression'; exprType?: 'AliasedExpression'; selectable?: true; expr: FirestorePipelineExpressionInternal; alias: string; as: string; } /** Serialized aliased aggregate node passed to native pipeline execute bridge. */ export interface FirestorePipelineAliasedAggregateInternal { __kind?: 'aliasedAggregate'; aggregate: FirestorePipelineAggregateFunctionInternal; alias: string; } export type FirestorePipelineExpressionInternal = | FirestorePipelineFieldExpressionInternal | FirestorePipelineConstantExpressionInternal | FirestorePipelineVariableExpressionInternal | FirestorePipelineFunctionExpressionInternal; export type FirestorePipelineSelectableInternal = | FirestorePipelineExpressionInternal | FirestorePipelineFlatAliasedFieldInternal | FirestorePipelineAliasedExpressionInternal; export type FirestorePipelineSerializedRecordInternal = { [key: string]: FirestorePipelineSerializedValueInternal; }; export type FirestorePipelineSerializedValueInternal = | null | boolean | number | string | FirestorePipelineExpressionInternal | FirestorePipelineAggregateFunctionInternal | FirestorePipelineOrderingInternal | FirestorePipelineFlatAliasedFieldInternal | FirestorePipelineAliasedExpressionInternal | FirestorePipelineAliasedAggregateInternal | FirestorePipelineSerializedInternal | FirestorePipelineSerializedValueInternal[] | FirestorePipelineSerializedRecordInternal; /** Serialized pipeline source passed to native execute bridge. */ export type FirestorePipelineSourceInternal = | { source: 'collection'; path: string; rawOptions?: Record; } | { source: 'collectionGroup'; collectionId: string; rawOptions?: Record; } | { source: 'database'; rawOptions?: Record; } | { source: 'documents'; documents: string[]; rawOptions?: Record; } | { source: 'query'; path: string; queryType: FirestoreQueryTypeInternal; filters: FirestoreFilterSpecInternal[]; orders: FirestoreOrderSpecInternal[]; options: FirestoreQueryOptionsInternal; } | { source: 'subcollection'; path: string; rawOptions?: Record; }; export type FirestorePipelineStageInternal = | { stage: 'where'; options: { condition: FirestorePipelineExpressionInternal; }; } | { stage: 'select'; options: { selections: Array; }; } | { stage: 'addFields'; options: { fields: FirestorePipelineSelectableInternal[]; }; } | { stage: 'removeFields'; options: { fields: Array; }; } | { stage: 'sort'; options: { orderings: FirestorePipelineOrderingInternal[]; }; } | { stage: 'limit'; options: { limit: number; }; } | { stage: 'offset'; options: { offset: number; }; } | { stage: 'aggregate'; options: { accumulators: FirestorePipelineAliasedAggregateInternal[]; groups?: Array; }; } | { stage: 'distinct'; options: { groups: Array; }; } | { stage: 'findNearest'; options: { field: string | FirestorePipelineFieldExpressionInternal; vectorValue: number[] | { values: number[] }; distanceMeasure: 'euclidean' | 'cosine' | 'dot_product'; limit?: number; distanceField?: string; }; } | { stage: 'search'; options: { query: FirestorePipelineExpressionInternal | string; languageCode?: string; retrievalDepth?: number; sort?: FirestorePipelineOrderingInternal[]; offset?: number; limit?: number; addFields?: FirestorePipelineSelectableInternal[]; }; } | { stage: 'define'; options: { variables: FirestorePipelineSelectableInternal[]; }; } | { stage: 'replaceWith'; options: { map: | string | FirestorePipelineExpressionInternal | FirestorePipelineFlatAliasedFieldInternal | FirestorePipelineAliasedExpressionInternal; }; } | { stage: 'sample'; options: { documents: number } | { percentage: number }; } | { stage: 'union'; options: { other: FirestorePipelineSerializedInternal; }; } | { stage: 'unnest'; options: { selectable: FirestorePipelineSelectableInternal; indexField?: string; }; } | { stage: 'rawStage'; options: { name: string; params?: FirestorePipelineSerializedValueInternal; options: Record; }; }; export type FirestorePipelineStageNameInternal = FirestorePipelineStageInternal['stage']; export type FirestorePipelineStageOptionsInternal< TStage extends FirestorePipelineStageNameInternal, > = Extract['options']; /** Serialized pipeline payload passed to native execute bridge. */ export interface FirestorePipelineSerializedInternal { source: FirestorePipelineSourceInternal; stages: FirestorePipelineStageInternal[]; } /** Options passed to native pipeline execute bridge. */ export interface FirestorePipelineExecuteOptionsInternal { indexMode?: 'recommended'; rawOptions?: Record; } /** Timestamp shape received from native pipeline execution. */ export type FirestorePipelineTimestampInternal = | Timestamp | { seconds?: number; nanoseconds?: number } | [number, number] | number; /** Single serialized pipeline result received from native execution. */ export interface FirestorePipelineResultInternal { data?: Record; path?: string; id?: string; createTime?: FirestorePipelineTimestampInternal; updateTime?: FirestorePipelineTimestampInternal; } /** Pipeline execution response received from native execution. */ export interface FirestorePipelineSnapshotInternal { results?: FirestorePipelineResultInternal[]; executionTime: FirestorePipelineTimestampInternal; } /** Options for snapshot listeners (includeMetadataChanges, source). */ export interface FirestoreSnapshotListenOptionsInternal { includeMetadataChanges?: boolean; source?: ListenSource; } /** Settings state on the Firestore module instance (ignoreUndefinedProperties, persistence). */ export interface FirestoreSettingsStateInternal { ignoreUndefinedProperties: boolean; persistence: boolean; } /** Subscription returned by emitter.addListener. */ export interface FirestoreEmitterSubscriptionInternal { remove(): void; } /** Native error shape in sync event body. */ export interface FirestoreSyncEventErrorInternal { code?: string; message?: string; } /** Serialized document snapshot from native (event.body.snapshot). */ export interface FirestoreDocumentSnapshotDataInternal { path: string; exists: boolean; data?: Record; dataEstimate?: Record; dataPrevious?: Record; dataNone?: Record; metadata: [boolean, boolean]; } /** Sync event body (document or collection) from native. */ export interface FirestoreSyncEventBodyInternal { error?: FirestoreSyncEventErrorInternal; snapshot?: FirestoreDocumentSnapshotDataInternal; documents?: FirestoreDocumentSnapshotDataInternal[]; } /** Emitter interface used by FirestoreInternal (matches FirebaseModule.emitter usage). */ export interface FirestoreEmitterInternal { addListener( eventName: string, callback: (event: { body: FirestoreSyncEventBodyInternal }) => void, ): FirestoreEmitterSubscriptionInternal; } /** * Wrapped native module interface for Firestore. * * Note: React Native Firebase internally wraps native methods and auto-prepends app name and * database ID when `hasMultiAppSupport` and `hasCustomUrlOrRegionSupport` are enabled. * Firestore uses multiple native modules (NativeRNFBTurboFirestore, NativeRNFBTurboFirestoreCollection, * NativeRNFBTurboFirestoreDocument, NativeRNFBTurboFirestoreTransaction) which are merged into a single * wrapped object. This interface represents that merged *wrapped* module shape exposed as * `this.native` within FirebaseFirestoreModule. */ export interface RNFBFirestoreModule { setLogLevel(level: LogLevel): Promise; // --- Main Firestore module (NativeRNFBTurboFirestore) --- loadBundle(bundle: string): Promise; clearPersistence(): Promise; waitForPendingWrites(): Promise; terminate(): Promise; useEmulator(host: string, port: number): void; disableNetwork(): Promise; enableNetwork(): Promise; settings(settings: object): Promise; addSnapshotsInSync(listenerId: number): void; removeSnapshotsInSync(listenerId: number): void; /** * Persistent cache index manager. * - 0: enableIndexAutoCreation * - 1: disableIndexAutoCreation * - 2: deleteAllIndexes */ persistenceCacheIndexManager(mode: number): Promise; // --- Collection module (NativeRNFBTurboFirestoreCollection) --- collectionOffSnapshot(listenerId: number): void; namedQueryOnSnapshot( queryName: string, type: FirestoreQueryTypeInternal | string, filters: FirestoreFilterSpecInternal[], orders: FirestoreOrderSpecInternal[], options: FirestoreQueryOptionsInternal, listenerId: number, snapshotListenOptions: FirestoreSnapshotListenOptionsInternal, ): void; collectionOnSnapshot( path: string, type: FirestoreQueryTypeInternal | string, filters: FirestoreFilterSpecInternal[], orders: FirestoreOrderSpecInternal[], options: FirestoreQueryOptionsInternal, listenerId: number, snapshotListenOptions: FirestoreSnapshotListenOptionsInternal, ): void; namedQueryGet( queryName: string, type: FirestoreQueryTypeInternal | string, filters: FirestoreFilterSpecInternal[], orders: FirestoreOrderSpecInternal[], options: FirestoreQueryOptionsInternal, getOptions?: { source?: string }, ): Promise; collectionGet( path: string, type: FirestoreQueryTypeInternal | string, filters: FirestoreFilterSpecInternal[], orders: FirestoreOrderSpecInternal[], options: FirestoreQueryOptionsInternal, getOptions?: { source?: string }, ): Promise; collectionCount( path: string, type: FirestoreQueryTypeInternal | string, filters: FirestoreFilterSpecInternal[], orders: FirestoreOrderSpecInternal[], options: FirestoreQueryOptionsInternal, ): Promise<{ count?: number }>; aggregateQuery( path: string, type: FirestoreQueryTypeInternal | string, filters: FirestoreFilterSpecInternal[], orders: FirestoreOrderSpecInternal[], options: FirestoreQueryOptionsInternal, aggregateQueries: FirestoreAggregateQuerySpecInternal[], ): Promise>; pipelineExecute( pipeline: FirestorePipelineSerializedInternal, options?: FirestorePipelineExecuteOptionsInternal, ): Promise; // --- Document module (NativeRNFBTurboFirestoreDocument) --- documentDelete(path: string): Promise; documentOffSnapshot(listenerId: number): void; documentOnSnapshot( path: string, listenerId: number, snapshotListenOptions: FirestoreSnapshotListenOptionsInternal, ): void; documentGet(path: string, getOptions?: { source?: string }): Promise; documentSet( path: string, data: Record, options: Record, ): Promise; documentUpdate(path: string, data: Record): Promise; documentBatch(writes: Array>): Promise; // --- Transaction module (NativeRNFBTurboFirestoreTransaction) --- transactionBegin(transactionId: number, maxAttempts?: number): Promise; transactionDispose(transactionId: number): void; transactionGetDocument(transactionId: number, path: string): Promise; transactionApplyBuffer(transactionId: number, commandBuffer: unknown[]): void; } declare module '@react-native-firebase/app/dist/module/internal/NativeModules' { interface ReactNativeFirebaseNativeModules { NativeRNFBTurboFirestore: RNFBFirestoreModule; NativeRNFBTurboFirestoreCollection: RNFBFirestoreModule; NativeRNFBTurboFirestoreDocument: RNFBFirestoreModule; NativeRNFBTurboFirestoreTransaction: RNFBFirestoreModule; } } // Helper type for internal wrappers that accept an optional trailing sentinel argument. export type WithModularDeprecationArg = F extends (...args: infer P) => infer R ? (...args: [...P, FirestoreModularDeprecationArg?]) => R : never; export interface ParentReferenceInternal< AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData, > { doc( path?: string, deprecationArg?: FirestoreModularDeprecationArg, ): DocumentReference; collection( path: string, deprecationArg?: FirestoreModularDeprecationArg, ): CollectionReference; } export interface ReferenceInternal< AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData, > { isEqual( other: | DocumentReference | CollectionReference, deprecationArg?: FirestoreModularDeprecationArg, ): boolean; } /** Used when calling query instance methods by name (e.g. in QueryConstraint._apply). */ export type QueryWithMethodInternal< AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData, > = Record Query>; /** Used when calling .where() on a query with a composite filter. */ export interface QueryWithWhereInternal< AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData, > { where(...args: unknown[]): Query; } /** Constraint instance that may have _apply(query) to apply itself to a query. */ export interface QueryConstraintWithApplyInternal< AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData, > { _apply?(query: Query): Query; } /** Filter constraint (field or composite) that exposes _filter. */ export interface QueryFilterConstraintWithFilterInternal { _filter: _Filter; } /** DocumentReference viewed as having get() returning DocumentSnapshot. */ export interface DocumentReferenceGetInternal< AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData, > { get(...args: unknown[]): Promise>; } /** DocumentReference viewed as having delete(). */ export interface DocumentReferenceDeleteInternal { delete(...args: unknown[]): Promise; } /** Reference or query viewed as having isEqual(). */ export interface ReferenceIsEqualInternal { isEqual(other: unknown, deprecationArg?: FirestoreModularDeprecationArg): boolean; } /** DocumentReference or Query viewed as having onSnapshot(). */ export interface ReferenceWithOnSnapshotInternal { onSnapshot(...listenerArgs: unknown[]): Unsubscribe; } /** Converter object with optional toFirestore (for guards before calling). */ export interface ConverterWithOptionalToFirestoreInternal { toFirestore?(data: unknown, options?: unknown): unknown; } /** Converter object with required toFirestore (after guard). */ export interface ConverterWithToFirestoreInternal { toFirestore: (data: unknown, options?: unknown) => unknown; } /** Partial snapshot listener observer (next / error only). */ export interface PartialSnapshotObserverInternal { next?: (snapshot: unknown) => void; error?: (e: Error) => void; } /** Converter object with optional toFirestore/fromFirestore (for validation). */ export interface ConverterWithOptionalMethodsInternal { toFirestore?: unknown; fromFirestore?: unknown; } /** Converter with required fromFirestore (for DocumentSnapshot.data() when converter is present). */ export interface ConverterWithFromFirestoreInternal { fromFirestore(snapshot: DocumentSnapshot, options?: SnapshotOptions): unknown; } /** Value at a field path in a document (primitive, nested object, or array). */ export type DocumentFieldValueInternal = Primitive | Record | unknown[]; export interface DocumentReferenceInternal< AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData, > extends ReferenceInternal, ParentReferenceInternal { set( data: WithFieldValue | PartialWithFieldValue, options?: SetOptions, deprecationArg?: FirestoreModularDeprecationArg, ): Promise; update( fieldOrUpdateData?: unknown, value?: unknown, ...moreFieldsAndValuesAndDeprecationArg: (unknown | FirestoreModularDeprecationArg)[] ): Promise; delete(deprecationArg?: FirestoreModularDeprecationArg): Promise; get( getOptions?: { source?: string }, deprecationArg?: FirestoreModularDeprecationArg, ): Promise; } export interface CollectionReferenceInternal< AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData, > extends ReferenceInternal, ParentReferenceInternal { add( data: WithFieldValue, deprecationArg?: FirestoreModularDeprecationArg, ): Promise>; } export interface QueryInternal< AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData, > extends ReferenceInternal { get( getOptions?: { source?: string }, deprecationArg?: FirestoreModularDeprecationArg, ): Promise>; count(deprecationArg?: FirestoreModularDeprecationArg): { get(): Promise }; where( queryConstraintOrFilter: unknown, deprecationArg?: FirestoreModularDeprecationArg, ): Query; withConstraints(...queryConstraints: QueryConstraint[]): Query; } export interface FirestoreInternal extends ParentReferenceInternal, Firestore { /** Wrapped native module (merged Firestore native modules). */ readonly native: RNFBFirestoreModule; /** Shared event emitter for sync events (document, collection, snapshots-in-sync). */ readonly emitter: FirestoreEmitterInternal; /** Builds app- and database-scoped event name. */ eventNameForApp(...args: Array): string; /** Module settings (e.g. ignoreUndefinedProperties for serialization). */ readonly _settings: FirestoreSettingsStateInternal; collectionGroup(collectionId: string, deprecationArg?: FirestoreModularDeprecationArg): Query; enableNetwork(deprecationArg?: FirestoreModularDeprecationArg): Promise; disableNetwork(deprecationArg?: FirestoreModularDeprecationArg): Promise; clearPersistence(deprecationArg?: FirestoreModularDeprecationArg): Promise; waitForPendingWrites(deprecationArg?: FirestoreModularDeprecationArg): Promise; terminate(deprecationArg?: FirestoreModularDeprecationArg): Promise; settings( settings: FirestoreSettings, deprecationArg?: FirestoreModularDeprecationArg, ): Promise; useEmulator( host: string, port: number, options?: unknown, deprecationArg?: FirestoreModularDeprecationArg, ): void; runTransaction( updateFunction: (transaction: Transaction) => Promise, options?: { maxAttempts?: number }, deprecationArg?: FirestoreModularDeprecationArg, ): Promise; loadBundle( bundleData: ReadableStream | ArrayBuffer | string, deprecationArg?: FirestoreModularDeprecationArg, ): LoadBundleTask; namedQuery(name: string, deprecationArg?: FirestoreModularDeprecationArg): Query | null; batch(deprecationArg?: FirestoreModularDeprecationArg): WriteBatch; persistentCacheIndexManager( deprecationArg?: FirestoreModularDeprecationArg, ): PersistentCacheIndexManager | null; } /** Firestore instance prototype shape used when installing pipeline() at runtime. */ export interface FirestorePipelinePrototypeInternal { pipeline?: (this: FirestoreInternal) => unknown; __rnfbFirestorePipelineInstalled__?: boolean; } export interface PersistentCacheIndexManagerInternal extends PersistentCacheIndexManager { enableIndexAutoCreation(deprecationArg?: FirestoreModularDeprecationArg): Promise; disableIndexAutoCreation(deprecationArg?: FirestoreModularDeprecationArg): Promise; deleteAllIndexes(deprecationArg?: FirestoreModularDeprecationArg): Promise; } export type FirestoreBlobInternal = Blob & { _binaryString: string }; export type QueryWithAggregateInternals = Query & { _firestore: FirestoreInternal; _collectionPath: { relativeName: string }; _modifiers: { type: FirestoreQueryTypeInternal; filters: FirestoreFilterSpecInternal[]; orders: FirestoreOrderSpecInternal[]; options: FirestoreQueryOptionsInternal; }; };