Cloud Firestore is Firebase's flexible, scalable NoSQL cloud database. It provides real-time synchronization, offline support, powerful querying capabilities, and automatic multi-region data replication. All Firestore functions are Zone-wrapped for proper Angular change detection.
Modern Angular standalone API for providing Firebase Firestore instances.
/**
* Provides Firebase Firestore instance using standalone API
* @param fn - Function that returns initialized Firestore instance
* @returns Environment providers for dependency injection
*/
export function provideFirestore(fn: () => Firestore): EnvironmentProviders;
/**
* Get Firebase Firestore instance
* @param app - Optional Firebase app instance
* @returns Firebase Firestore instance
*/
export function getFirestore(app?: FirebaseApp): Firestore;Traditional NgModule API for providing Firebase Firestore instances.
/**
* Firebase Firestore NgModule for traditional module-based setup
*/
export class FirestoreModule {
static forRoot(): ModuleWithProviders<FirestoreModule>;
}Injectable services for accessing Firebase Firestore instances in Angular components.
/**
* Injectable service providing access to Firebase Firestore instance
*/
export class Firestore extends Firestore {}
/**
* Collection of all Firebase Firestore instances
*/
export class FirestoreInstances extends Array<Firestore> {}
/**
* Observable stream of Firebase Firestore instances
*/
export const firestoreInstance$: Observable<Firestore>;Core functions for working with individual documents.
/**
* Get document reference
* @param firestore - Firestore instance
* @param path - Document path (e.g., 'users/userId')
* @returns Document reference
*/
export function doc(firestore: Firestore, path: string): DocumentReference;
/**
* Get document reference with typed data
* @param firestore - Firestore instance
* @param path - Document path
* @returns Typed document reference
*/
export function doc<T>(firestore: Firestore, path: string): DocumentReference<T>;
/**
* Set document data (overwrites existing data)
* @param ref - Document reference
* @param data - Document data
* @returns Promise that resolves when write completes
*/
export function setDoc<T>(ref: DocumentReference<T>, data: T): Promise<void>;
/**
* Set document data with merge options
* @param ref - Document reference
* @param data - Partial document data
* @param options - Set options with merge
* @returns Promise that resolves when write completes
*/
export function setDoc<T>(
ref: DocumentReference<T>,
data: Partial<T>,
options: SetOptions
): Promise<void>;
/**
* Update document fields
* @param ref - Document reference
* @param data - Fields to update
* @returns Promise that resolves when update completes
*/
export function updateDoc<T>(
ref: DocumentReference<T>,
data: Partial<T>
): Promise<void>;
/**
* Update specific document fields with field paths
* @param ref - Document reference
* @param field - Field name or path
* @param value - Field value
* @param moreFieldsAndValues - Additional field-value pairs
* @returns Promise that resolves when update completes
*/
export function updateDoc(
ref: DocumentReference,
field: string | FieldPath,
value: any,
...moreFieldsAndValues: any[]
): Promise<void>;
/**
* Delete document
* @param ref - Document reference
* @returns Promise that resolves when delete completes
*/
export function deleteDoc(ref: DocumentReference): Promise<void>;
/**
* Get document snapshot
* @param ref - Document reference
* @returns Promise resolving to document snapshot
*/
export function getDoc<T>(ref: DocumentReference<T>): Promise<DocumentSnapshot<T>>;Functions for working with collections of documents.
/**
* Get collection reference
* @param firestore - Firestore instance
* @param path - Collection path (e.g., 'users')
* @returns Collection reference
*/
export function collection(firestore: Firestore, path: string): CollectionReference;
/**
* Get typed collection reference
* @param firestore - Firestore instance
* @param path - Collection path
* @returns Typed collection reference
*/
export function collection<T>(
firestore: Firestore,
path: string
): CollectionReference<T>;
/**
* Add document to collection with auto-generated ID
* @param ref - Collection reference
* @param data - Document data
* @returns Promise resolving to new document reference
*/
export function addDoc<T>(
ref: CollectionReference<T>,
data: T
): Promise<DocumentReference<T>>;
/**
* Get documents from collection or query
* @param query - Collection reference or query
* @returns Promise resolving to query snapshot
*/
export function getDocs<T>(query: Query<T>): Promise<QuerySnapshot<T>>;Advanced querying capabilities for filtering, ordering, and limiting data.
/**
* Create query with constraints
* @param query - Base query (collection reference or existing query)
* @param queryConstraints - Query constraints (where, orderBy, limit, etc.)
* @returns New query with applied constraints
*/
export function query<T>(
query: Query<T>,
...queryConstraints: QueryConstraint[]
): Query<T>;
/**
* Create where clause constraint
* @param fieldPath - Field path to filter on
* @param opStr - Comparison operator
* @param value - Value to compare against
* @returns Query constraint
*/
export function where(
fieldPath: string | FieldPath,
opStr: WhereFilterOp,
value: any
): QueryConstraint;
/**
* Create order by constraint
* @param fieldPath - Field path to order by
* @param directionStr - Sort direction ('asc' or 'desc')
* @returns Query constraint
*/
export function orderBy(
fieldPath: string | FieldPath,
directionStr?: OrderByDirection
): QueryConstraint;
/**
* Create limit constraint
* @param limit - Maximum number of documents to return
* @returns Query constraint
*/
export function limit(limit: number): QueryConstraint;
/**
* Create limit to last constraint
* @param limit - Maximum number of documents to return from end
* @returns Query constraint
*/
export function limitToLast(limit: number): QueryConstraint;
/**
* Create start at constraint
* @param snapshot - Document snapshot to start at
* @returns Query constraint
*/
export function startAt(snapshot: DocumentSnapshot): QueryConstraint;
/**
* Create start at constraint with field values
* @param fieldValues - Field values to start at
* @returns Query constraint
*/
export function startAt(...fieldValues: any[]): QueryConstraint;
/**
* Create start after constraint
* @param snapshot - Document snapshot to start after
* @returns Query constraint
*/
export function startAfter(snapshot: DocumentSnapshot): QueryConstraint;
/**
* Create end at constraint
* @param snapshot - Document snapshot to end at
* @returns Query constraint
*/
export function endAt(snapshot: DocumentSnapshot): QueryConstraint;
/**
* Create end before constraint
* @param snapshot - Document snapshot to end before
* @returns Query constraint
*/
export function endBefore(snapshot: DocumentSnapshot): QueryConstraint;Functions for listening to real-time document and collection changes.
/**
* Listen to document changes
* @param ref - Document reference
* @param observer - Callback function or observer object
* @returns Unsubscribe function
*/
export function onSnapshot<T>(
ref: DocumentReference<T>,
observer: (snapshot: DocumentSnapshot<T>) => void
): Unsubscribe;
/**
* Listen to document changes with error handling
* @param ref - Document reference
* @param observer - Observer object with next, error, and complete handlers
* @returns Unsubscribe function
*/
export function onSnapshot<T>(
ref: DocumentReference<T>,
observer: {
next?: (snapshot: DocumentSnapshot<T>) => void;
error?: (error: FirestoreError) => void;
complete?: () => void;
}
): Unsubscribe;
/**
* Listen to query changes
* @param query - Query to listen to
* @param observer - Callback function or observer object
* @returns Unsubscribe function
*/
export function onSnapshot<T>(
query: Query<T>,
observer: (snapshot: QuerySnapshot<T>) => void
): Unsubscribe;
/**
* Listen to query changes with options
* @param query - Query to listen to
* @param options - Snapshot listener options
* @param observer - Callback function or observer object
* @returns Unsubscribe function
*/
export function onSnapshot<T>(
query: Query<T>,
options: SnapshotListenOptions,
observer: (snapshot: QuerySnapshot<T>) => void
): Unsubscribe;Reactive streams for Firestore data using RxJS Observables.
/**
* Observable of document data
* @param ref - Document reference
* @returns Observable stream of document data or undefined
*/
export function docData<T>(ref: DocumentReference<T>): Observable<T | undefined>;
/**
* Observable of document data with options
* @param ref - Document reference
* @param options - Observable options
* @returns Observable stream of document data
*/
export function docData<T>(
ref: DocumentReference<T>,
options: { idField?: string }
): Observable<T | undefined>;
/**
* Observable of document snapshots
* @param ref - Document reference
* @returns Observable stream of document snapshots
*/
export function docSnapshots<T>(ref: DocumentReference<T>): Observable<DocumentSnapshot<T>>;
/**
* Observable of collection data
* @param ref - Collection reference or query
* @returns Observable stream of document data array
*/
export function collectionData<T>(ref: CollectionReference<T> | Query<T>): Observable<T[]>;
/**
* Observable of collection data with options
* @param ref - Collection reference or query
* @param options - Observable options
* @returns Observable stream of document data array
*/
export function collectionData<T>(
ref: CollectionReference<T> | Query<T>,
options: { idField?: string }
): Observable<T[]>;
/**
* Observable of collection snapshots
* @param ref - Collection reference or query
* @returns Observable stream of query snapshots
*/
export function collectionSnapshots<T>(
ref: CollectionReference<T> | Query<T>
): Observable<QuerySnapshot<T>>;
/**
* Observable of collection changes with action types
* @param ref - Collection reference or query
* @returns Observable stream of document changes
*/
export function collectionChanges<T>(
ref: CollectionReference<T> | Query<T>
): Observable<DocumentChange<T>[]>;
/**
* Observable of sorted collection changes
* @param ref - Collection reference or query
* @param events - Array of change types to listen for
* @returns Observable stream of sorted document changes
*/
export function sortedChanges<T>(
ref: CollectionReference<T> | Query<T>,
events?: DocumentChangeType[]
): Observable<DocumentChange<T>[]>;
/**
* Observable audit trail of all document changes
* @param ref - Collection reference or query
* @returns Observable stream of audit trail entries
*/
export function auditTrail<T>(
ref: CollectionReference<T> | Query<T>
): Observable<AuditTrail<T>[]>;Functions for atomic operations across multiple documents.
/**
* Run transaction
* @param firestore - Firestore instance
* @param updateFunction - Transaction update function
* @returns Promise resolving to transaction result
*/
export function runTransaction<T>(
firestore: Firestore,
updateFunction: (transaction: Transaction) => Promise<T>
): Promise<T>;
/**
* Create write batch
* @param firestore - Firestore instance
* @returns WriteBatch instance for batched operations
*/
export function writeBatch(firestore: Firestore): WriteBatch;
/**
* Transaction interface for atomic operations
*/
interface Transaction {
get<T>(documentRef: DocumentReference<T>): Promise<DocumentSnapshot<T>>;
set<T>(documentRef: DocumentReference<T>, data: T): Transaction;
set<T>(documentRef: DocumentReference<T>, data: Partial<T>, options: SetOptions): Transaction;
update<T>(documentRef: DocumentReference<T>, data: Partial<T>): Transaction;
delete(documentRef: DocumentReference): Transaction;
}
/**
* Write batch interface for batched operations
*/
interface WriteBatch {
set<T>(documentRef: DocumentReference<T>, data: T): WriteBatch;
set<T>(documentRef: DocumentReference<T>, data: Partial<T>, options: SetOptions): WriteBatch;
update<T>(documentRef: DocumentReference<T>, data: Partial<T>): WriteBatch;
delete(documentRef: DocumentReference): WriteBatch;
commit(): Promise<void>;
}Configuration and utility functions for Firestore.
/**
* Connect to Firestore emulator
* @param firestore - Firestore instance
* @param host - Emulator host
* @param port - Emulator port
* @param options - Optional connection settings
*/
export function connectFirestoreEmulator(
firestore: Firestore,
host: string,
port: number,
options?: { mockUserToken?: EmulatorMockTokenOptions | string }
): void;
/**
* Enable network connectivity
* @param firestore - Firestore instance
* @returns Promise that resolves when network is enabled
*/
export function enableNetwork(firestore: Firestore): Promise<void>;
/**
* Disable network connectivity
* @param firestore - Firestore instance
* @returns Promise that resolves when network is disabled
*/
export function disableNetwork(firestore: Firestore): Promise<void>;
/**
* Enable IndexedDB persistence
* @param firestore - Firestore instance
* @param persistenceSettings - Optional persistence settings
* @returns Promise that resolves when persistence is enabled
*/
export function enableIndexedDbPersistence(
firestore: Firestore,
persistenceSettings?: PersistenceSettings
): Promise<void>;
/**
* Clear IndexedDB persistence
* @param firestore - Firestore instance
* @returns Promise that resolves when persistence is cleared
*/
export function clearIndexedDbPersistence(firestore: Firestore): Promise<void>;
/**
* Wait for pending writes to complete
* @param firestore - Firestore instance
* @returns Promise that resolves when writes are complete
*/
export function waitForPendingWrites(firestore: Firestore): Promise<void>;/**
* Firestore database instance
*/
interface Firestore {
readonly app: FirebaseApp;
}
/**
* Document reference
*/
interface DocumentReference<T = DocumentData> {
readonly id: string;
readonly path: string;
readonly parent: CollectionReference<T>;
readonly firestore: Firestore;
}
/**
* Collection reference
*/
interface CollectionReference<T = DocumentData> extends Query<T> {
readonly id: string;
readonly path: string;
readonly parent: DocumentReference | null;
}
/**
* Query interface
*/
interface Query<T = DocumentData> {
readonly firestore: Firestore;
}
/**
* Document snapshot
*/
interface DocumentSnapshot<T = DocumentData> {
readonly id: string;
readonly ref: DocumentReference<T>;
readonly metadata: SnapshotMetadata;
exists(): boolean;
data(): T | undefined;
get(fieldPath: string | FieldPath): any;
}
/**
* Query snapshot
*/
interface QuerySnapshot<T = DocumentData> {
readonly docs: QueryDocumentSnapshot<T>[];
readonly size: number;
readonly empty: boolean;
readonly metadata: SnapshotMetadata;
forEach(callback: (result: QueryDocumentSnapshot<T>) => void): void;
}
/**
* Query document snapshot
*/
interface QueryDocumentSnapshot<T = DocumentData> extends DocumentSnapshot<T> {
data(): T;
}/**
* Where filter operators
*/
type WhereFilterOp =
| '<'
| '<='
| '=='
| '!='
| '>='
| '>'
| 'array-contains'
| 'in'
| 'not-in'
| 'array-contains-any';
/**
* Order by direction
*/
type OrderByDirection = 'desc' | 'asc';
/**
* Document change type
*/
type DocumentChangeType = 'added' | 'removed' | 'modified';
/**
* Document change
*/
interface DocumentChange<T = DocumentData> {
readonly type: DocumentChangeType;
readonly doc: QueryDocumentSnapshot<T>;
readonly oldIndex: number;
readonly newIndex: number;
}
/**
* Field path for nested field access
*/
class FieldPath {
constructor(...fieldNames: string[]);
static documentId(): FieldPath;
}/**
* Set options for document writes
*/
interface SetOptions {
readonly merge?: boolean;
readonly mergeFields?: (string | FieldPath)[];
}
/**
* Snapshot listener options
*/
interface SnapshotListenOptions {
readonly includeMetadataChanges?: boolean;
}
/**
* Snapshot metadata
*/
interface SnapshotMetadata {
readonly hasPendingWrites: boolean;
readonly fromCache: boolean;
}
/**
* Persistence settings
*/
interface PersistenceSettings {
readonly synchronizeTabs?: boolean;
readonly experimentalForceOwningTab?: boolean;
}/**
* Firestore error
*/
interface FirestoreError extends Error {
readonly code: FirestoreErrorCode;
readonly message: string;
}
/**
* Firestore error codes
*/
type FirestoreErrorCode =
| 'cancelled'
| 'unknown'
| 'invalid-argument'
| 'deadline-exceeded'
| 'not-found'
| 'already-exists'
| 'permission-denied'
| 'resource-exhausted'
| 'failed-precondition'
| 'aborted'
| 'out-of-range'
| 'unimplemented'
| 'internal'
| 'unavailable'
| 'data-loss'
| 'unauthenticated';import { Component, inject } from '@angular/core';
import { Firestore, doc, setDoc, getDoc, updateDoc, deleteDoc } from '@angular/fire/firestore';
@Component({
selector: 'app-firestore-basic',
template: `...`,
})
export class FirestoreBasicComponent {
private firestore = inject(Firestore);
async createUser(userId: string, userData: any) {
const userRef = doc(this.firestore, 'users', userId);
await setDoc(userRef, userData);
console.log('User created');
}
async getUser(userId: string) {
const userRef = doc(this.firestore, 'users', userId);
const snapshot = await getDoc(userRef);
if (snapshot.exists()) {
console.log('User data:', snapshot.data());
return snapshot.data();
} else {
console.log('User not found');
return null;
}
}
async updateUser(userId: string, updates: any) {
const userRef = doc(this.firestore, 'users', userId);
await updateDoc(userRef, updates);
console.log('User updated');
}
async deleteUser(userId: string) {
const userRef = doc(this.firestore, 'users', userId);
await deleteDoc(userRef);
console.log('User deleted');
}
}import { Component, inject } from '@angular/core';
import {
Firestore,
collection,
query,
where,
orderBy,
limit,
collectionData
} from '@angular/fire/firestore';
import { map } from 'rxjs/operators';
interface User {
id: string;
name: string;
email: string;
active: boolean;
createdAt: Date;
}
@Component({
selector: 'app-firestore-query',
template: `
<div *ngFor="let user of activeUsers$ | async">
<h3>{{ user.name }}</h3>
<p>{{ user.email }}</p>
</div>
`,
})
export class FirestoreQueryComponent {
private firestore = inject(Firestore);
// Get active users ordered by creation date
activeUsers$ = collectionData(
query(
collection(this.firestore, 'users'),
where('active', '==', true),
orderBy('createdAt', 'desc'),
limit(10)
),
{ idField: 'id' }
).pipe(
map(users => users as User[])
);
// Get users by email domain
getUsersByDomain(domain: string) {
return collectionData(
query(
collection(this.firestore, 'users'),
where('email', '>=', `@${domain}`),
where('email', '<', `@${domain}\uf8ff`)
),
{ idField: 'id' }
);
}
}import { Component, inject, OnDestroy } from '@angular/core';
import { Firestore, doc, onSnapshot } from '@angular/fire/firestore';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-realtime-doc',
template: `
<div *ngIf="userData">
<h2>{{ userData.name }}</h2>
<p>Status: {{ userData.status }}</p>
<p>Last Updated: {{ userData.lastUpdated?.toDate() | date }}</p>
</div>
`,
})
export class RealtimeDocComponent implements OnDestroy {
private firestore = inject(Firestore);
private unsubscribe?: () => void;
userData: any = null;
ngOnInit() {
const userRef = doc(this.firestore, 'users', 'user123');
this.unsubscribe = onSnapshot(userRef, (snapshot) => {
if (snapshot.exists()) {
this.userData = snapshot.data();
console.log('User data updated:', this.userData);
} else {
this.userData = null;
console.log('User document does not exist');
}
}, (error) => {
console.error('Error listening to user changes:', error);
});
}
ngOnDestroy() {
if (this.unsubscribe) {
this.unsubscribe();
}
}
}import { Component, inject } from '@angular/core';
import {
Firestore,
doc,
runTransaction,
writeBatch,
getDoc,
increment
} from '@angular/fire/firestore';
@Component({
selector: 'app-firestore-transaction',
template: `...`,
})
export class FirestoreTransactionComponent {
private firestore = inject(Firestore);
async transferPoints(fromUserId: string, toUserId: string, points: number) {
const fromRef = doc(this.firestore, 'users', fromUserId);
const toRef = doc(this.firestore, 'users', toUserId);
try {
await runTransaction(this.firestore, async (transaction) => {
const fromSnapshot = await transaction.get(fromRef);
if (!fromSnapshot.exists()) {
throw new Error('Source user does not exist');
}
const fromData = fromSnapshot.data();
if (fromData['points'] < points) {
throw new Error('Insufficient points');
}
transaction.update(fromRef, { points: increment(-points) });
transaction.update(toRef, { points: increment(points) });
});
console.log('Points transferred successfully');
} catch (error) {
console.error('Transaction error:', error);
}
}
async batchUpdateUsers(updates: { id: string; data: any }[]) {
const batch = writeBatch(this.firestore);
updates.forEach(update => {
const userRef = doc(this.firestore, 'users', update.id);
batch.update(userRef, update.data);
});
try {
await batch.commit();
console.log('Batch update completed');
} catch (error) {
console.error('Batch update error:', error);
}
}
}