CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-native-firebase--firestore

React Native Firebase Cloud Firestore provides a NoSQL document database with real-time synchronization capabilities.

Pending
Overview
Eval results
Files

querying-filtering.mddocs/

Querying & Filtering

Advanced query capabilities with filtering, ordering, pagination, and aggregation. Supports both simple field queries and complex composite filters.

Capabilities

Basic Query Operations

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' });

Where Clauses

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();

Composite Filters

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)
    )
  );

Ordering

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();

Pagination

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);

Aggregation Queries

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);

Types

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

docs

data-types.md

database-operations.md

index.md

modular-api.md

offline-network.md

querying-filtering.md

realtime-sync.md

transactions-batches.md

tile.json