React Native Firebase Cloud Firestore provides a NoSQL document database with real-time synchronization capabilities.
—
Advanced query capabilities with filtering, ordering, pagination, and aggregation. Supports both simple field queries and complex composite filters.
Execute queries to retrieve documents with optional source specification.
interface Query<T = FirebaseFirestoreTypes.DocumentData> {
/**
* Execute the query and get results
* @param options - Optional get options to specify data source
* @returns Promise resolving to query snapshot
*/
get(options?: FirebaseFirestoreTypes.GetOptions): Promise<FirebaseFirestoreTypes.QuerySnapshot<T>>;
/**
* Check if two queries are equal
* @param other - Other query to compare
* @returns True if queries are equal
*/
isEqual(other: FirebaseFirestoreTypes.Query): boolean;
}
interface QuerySnapshot<T = FirebaseFirestoreTypes.DocumentData> {
readonly docs: FirebaseFirestoreTypes.QueryDocumentSnapshot<T>[];
readonly empty: boolean;
readonly metadata: FirebaseFirestoreTypes.SnapshotMetadata;
readonly query: FirebaseFirestoreTypes.Query<T>;
readonly size: number;
/**
* Get array of document changes since last snapshot
* @param options - Optional listen options
* @returns Array of document changes
*/
docChanges(options?: FirebaseFirestoreTypes.SnapshotListenOptions): FirebaseFirestoreTypes.DocumentChange<T>[];
/**
* Iterate over all documents in the snapshot
* @param callback - Function to call for each document
* @param thisArg - Optional this context
*/
forEach(callback: (result: FirebaseFirestoreTypes.QueryDocumentSnapshot<T>) => void, thisArg?: any): void;
}Usage Examples:
import firestore from '@react-native-firebase/firestore';
// Execute basic query
const snapshot = await firestore().collection('users').get();
// Process results
snapshot.forEach(doc => {
console.log(doc.id, '=>', doc.data());
});
// Check if query returned results
if (!snapshot.empty) {
console.log(`Found ${snapshot.size} users`);
}
// Get from specific source
const serverSnapshot = await firestore()
.collection('users')
.get({ source: 'server' });Filter documents based on field values using various comparison operators.
/**
* Filter query results based on field values
* @param fieldPath - Field to filter on (string or FieldPath)
* @param opStr - Comparison operator
* @param value - Value to compare against
* @returns New query with filter applied
*/
where(fieldPath: keyof T | FirebaseFirestoreTypes.FieldPath, opStr: FirebaseFirestoreTypes.WhereFilterOp, value: any): FirebaseFirestoreTypes.Query<T>;
/**
* Apply a filter constraint to the query
* @param filter - Query filter constraint
* @returns New query with filter applied
*/
where(filter: FirebaseFirestoreTypes.QueryFilterConstraint): FirebaseFirestoreTypes.Query<T>;
type WhereFilterOp =
| '<' | '<=' | '==' | '>' | '>=' | '!='
| 'array-contains' | 'array-contains-any'
| 'in' | 'not-in';Usage Examples:
import firestore from '@react-native-firebase/firestore';
// Equal comparison
const activeUsers = await firestore()
.collection('users')
.where('active', '==', true)
.get();
// Numeric comparisons
const adultsQuery = firestore()
.collection('users')
.where('age', '>=', 18);
// Array operations
const moderatorsQuery = firestore()
.collection('users')
.where('roles', 'array-contains', 'moderator');
// In operator for multiple values
const specificUsersQuery = firestore()
.collection('users')
.where('userId', 'in', ['user1', 'user2', 'user3']);
// Not equal (requires composite index)
const nonAdminQuery = firestore()
.collection('users')
.where('role', '!=', 'admin');
// Using FieldPath for nested fields
const verifiedEmailQuery = firestore()
.collection('users')
.where(new firestore.FieldPath('profile', 'emailVerified'), '==', true);
// Chain multiple where clauses
const queryResults = await firestore()
.collection('users')
.where('active', '==', true)
.where('age', '>=', 18)
.where('city', '==', 'New York')
.get();Combine multiple filter conditions using AND/OR logic.
/**
* Create field filter constraint
* @param fieldPath - Field to filter on
* @param operator - Comparison operator
* @param value - Value to compare against
* @returns Query field filter constraint
*/
Filter(fieldPath: keyof T | FirebaseFirestoreTypes.FieldPath, operator: FirebaseFirestoreTypes.WhereFilterOp, value: any): FirebaseFirestoreTypes.QueryFieldFilterConstraint;
/**
* Combine filter constraints with AND logic
* @param queries - Filter constraints to combine
* @returns Composite AND filter constraint
*/
Filter.and(...queries: FirebaseFirestoreTypes.QueryFilterConstraint[]): FirebaseFirestoreTypes.QueryCompositeFilterConstraint;
/**
* Combine filter constraints with OR logic
* @param queries - Filter constraints to combine
* @returns Composite OR filter constraint
*/
Filter.or(...queries: FirebaseFirestoreTypes.QueryFilterConstraint[]): FirebaseFirestoreTypes.QueryCompositeFilterConstraint;Usage Examples:
import firestore, { Filter } from '@react-native-firebase/firestore';
// OR filter - users who are either admin or moderator
const adminOrModeratorQuery = firestore()
.collection('users')
.where(
Filter.or(
Filter('role', '==', 'admin'),
Filter('role', '==', 'moderator')
)
);
// AND filter - active users in New York
const activeNYUsersQuery = firestore()
.collection('users')
.where(
Filter.and(
Filter('active', '==', true),
Filter('city', '==', 'New York')
)
);
// Complex nested filters - (admin OR moderator) AND active
const complexQuery = firestore()
.collection('users')
.where(
Filter.and(
Filter.or(
Filter('role', '==', 'admin'),
Filter('role', '==', 'moderator')
),
Filter('active', '==', true)
)
);Sort query results by one or more fields in ascending or descending order.
/**
* Order query results by a field
* @param fieldPath - Field to order by (string or FieldPath)
* @param directionStr - Sort direction ('asc' or 'desc')
* @returns New query with ordering applied
*/
orderBy(fieldPath: keyof T | string | FirebaseFirestoreTypes.FieldPath, directionStr?: 'asc' | 'desc'): FirebaseFirestoreTypes.Query<T>;Usage Examples:
import firestore from '@react-native-firebase/firestore';
// Order by creation date (ascending by default)
const chronologicalQuery = firestore()
.collection('posts')
.orderBy('createdAt');
// Order by creation date descending (most recent first)
const recentPostsQuery = firestore()
.collection('posts')
.orderBy('createdAt', 'desc');
// Multiple ordering criteria
const sortedUsersQuery = firestore()
.collection('users')
.orderBy('lastName')
.orderBy('firstName')
.orderBy('createdAt', 'desc');
// Order by nested field
const sortedByProfileQuery = firestore()
.collection('users')
.orderBy(new firestore.FieldPath('profile', 'displayName'));
// Combine with filtering (requires composite index)
const filteredAndSortedQuery = await firestore()
.collection('users')
.where('active', '==', true)
.orderBy('lastLoginAt', 'desc')
.get();Limit result sets and implement cursor-based pagination for large datasets.
/**
* Limit the number of documents returned
* @param limit - Maximum number of documents to return
* @returns New query with limit applied
*/
limit(limit: number): FirebaseFirestoreTypes.Query<T>;
/**
* Limit to last N documents (requires orderBy)
* @param limitToLast - Number of documents from the end
* @returns New query with limit applied
*/
limitToLast(limitToLast: number): FirebaseFirestoreTypes.Query<T>;
/**
* Start results at a document snapshot
* @param snapshot - Document snapshot to start at
* @returns New query with cursor applied
*/
startAt(snapshot: FirebaseFirestoreTypes.DocumentSnapshot<T>): FirebaseFirestoreTypes.Query<T>;
/**
* Start results at field values
* @param fieldValues - Field values to start at
* @returns New query with cursor applied
*/
startAt(...fieldValues: any[]): FirebaseFirestoreTypes.Query<T>;
/**
* Start results after a document snapshot
* @param snapshot - Document snapshot to start after
* @returns New query with cursor applied
*/
startAfter(snapshot: FirebaseFirestoreTypes.DocumentSnapshot<T>): FirebaseFirestoreTypes.Query<T>;
/**
* Start results after field values
* @param fieldValues - Field values to start after
* @returns New query with cursor applied
*/
startAfter(...fieldValues: any[]): FirebaseFirestoreTypes.Query<T>;
/**
* End results at a document snapshot
* @param snapshot - Document snapshot to end at
* @returns New query with cursor applied
*/
endAt(snapshot: FirebaseFirestoreTypes.DocumentSnapshot<T>): FirebaseFirestoreTypes.Query<T>;
/**
* End results at field values
* @param fieldValues - Field values to end at
* @returns New query with cursor applied
*/
endAt(...fieldValues: any[]): FirebaseFirestoreTypes.Query<T>;
/**
* End results before a document snapshot
* @param snapshot - Document snapshot to end before
* @returns New query with cursor applied
*/
endBefore(snapshot: FirebaseFirestoreTypes.DocumentSnapshot<T>): FirebaseFirestoreTypes.Query<T>;
/**
* End results before field values
* @param fieldValues - Field values to end before
* @returns New query with cursor applied
*/
endBefore(...fieldValues: any[]): FirebaseFirestoreTypes.Query<T>;Usage Examples:
import firestore from '@react-native-firebase/firestore';
// Basic pagination - first page
const firstPageQuery = firestore()
.collection('posts')
.orderBy('createdAt', 'desc')
.limit(10);
const firstPage = await firstPageQuery.get();
// Next page using last document as cursor
if (!firstPage.empty) {
const lastDoc = firstPage.docs[firstPage.docs.length - 1];
const nextPageQuery = firestore()
.collection('posts')
.orderBy('createdAt', 'desc')
.startAfter(lastDoc)
.limit(10);
const nextPage = await nextPageQuery.get();
}
// Get last N documents
const lastPostsQuery = firestore()
.collection('posts')
.orderBy('createdAt')
.limitToLast(5);
// Pagination with field values
const postsAfterDateQuery = firestore()
.collection('posts')
.orderBy('createdAt')
.startAfter(new Date('2023-01-01'))
.limit(10);
// Range queries using cursors
const specificRangeQuery = firestore()
.collection('users')
.orderBy('age')
.startAt(18)
.endBefore(65)
.limit(50);Perform server-side aggregations like counting documents without downloading all data.
/**
* Count the number of documents in the query
* @returns Aggregate query for counting documents
*/
count(): FirebaseFirestoreTypes.AggregateQuery<{ count: FirebaseFirestoreTypes.AggregateField<number> }>;
/**
* Count the number of documents on the server
* @returns Aggregate query for server-side counting
*/
countFromServer(): FirebaseFirestoreTypes.AggregateQuery<{ count: FirebaseFirestoreTypes.AggregateField<number> }>;
interface AggregateQuery<T> {
/**
* Execute the aggregate query
* @returns Promise resolving to aggregate query snapshot
*/
get(): Promise<FirebaseFirestoreTypes.AggregateQuerySnapshot<T>>;
}
interface AggregateQuerySnapshot<T> {
/**
* Get aggregate data
* @returns Aggregate data object
*/
data(): T;
}Usage Examples:
import firestore from '@react-native-firebase/firestore';
// Count all users
const allUsersCount = await firestore()
.collection('users')
.count()
.get();
console.log('Total users:', allUsersCount.data().count);
// Count with filters
const activeUsersCount = await firestore()
.collection('users')
.where('active', '==', true)
.count()
.get();
console.log('Active users:', activeUsersCount.data().count);
// Server-side counting (bypasses cache)
const serverCount = await firestore()
.collection('posts')
.where('published', '==', true)
.countFromServer()
.get();
console.log('Published posts:', serverCount.data().count);interface DocumentChange<T = FirebaseFirestoreTypes.DocumentData> {
readonly doc: FirebaseFirestoreTypes.QueryDocumentSnapshot<T>;
readonly newIndex: number;
readonly oldIndex: number;
readonly type: FirebaseFirestoreTypes.DocumentChangeType;
}
type DocumentChangeType = 'added' | 'removed' | 'modified';
interface QueryDocumentSnapshot<T = FirebaseFirestoreTypes.DocumentData> extends DocumentSnapshot<T> {
/**
* QueryDocumentSnapshot always contains data (exists is always true)
*/
data(options?: FirebaseFirestoreTypes.SnapshotOptions): T;
}
interface AggregateField<T> {
/**
* Get the aggregate field value
* @returns The aggregated value
*/
value(): T;
}Install with Tessl CLI
npx tessl i tessl/npm-react-native-firebase--firestore