CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-firebase--firestore-types

TypeScript type definitions for Firebase Firestore providing comprehensive type safety for database operations

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

collections-queries.mddocs/

Collections and Queries

Types for collection references, query building, and query result handling including filtering, ordering, and pagination.

Capabilities

CollectionReference Class

Reference to a Firestore collection, extending Query with collection-specific operations.

class CollectionReference<T = DocumentData, T2 extends DocumentData = DocumentData> extends Query<T, T2> {
  private constructor();
  
  /** Collection ID */
  readonly id: string;
  
  /** Parent document reference, or null for root collections */
  readonly parent: DocumentReference<DocumentData> | null;
  
  /** Full collection path */
  readonly path: string;
  
  /** Get a document reference in this collection */
  doc(documentPath?: string): DocumentReference<T>;
  
  /** Add a new document to this collection */
  add(data: T): Promise<DocumentReference<T>>;
  
  /** Check if this reference equals another */
  isEqual(other: CollectionReference<T>): boolean;
  
  /** Convert this reference to use a different data type */
  withConverter(converter: null): CollectionReference<DocumentData>;
  withConverter<U>(
    converter: FirestoreDataConverter<U>
  ): CollectionReference<U>;
}

Query Class

Base class for building and executing Firestore queries.

class Query<T = DocumentData, T2 extends DocumentData = DocumentData> {
  protected constructor();
  
  /** Firestore instance this query belongs to */
  readonly firestore: FirebaseFirestore;
  
  /** Filter documents where field matches condition */
  where(
    fieldPath: string | FieldPath,
    opStr: WhereFilterOp,
    value: any
  ): Query<T>;
  
  /** Order results by field */
  orderBy(
    fieldPath: string | FieldPath,
    directionStr?: OrderByDirection
  ): Query<T>;
  
  /** Limit number of results */
  limit(limit: number): Query<T>;
  
  /** Limit to last N results (requires orderBy) */
  limitToLast(limit: number): Query<T>;
  
  /** Start results at document snapshot */
  startAt(snapshot: DocumentSnapshot<any>): Query<T>;
  /** Start results at field values */
  startAt(...fieldValues: any[]): Query<T>;
  
  /** Start results after document snapshot */
  startAfter(snapshot: DocumentSnapshot<any>): Query<T>;
  /** Start results after field values */
  startAfter(...fieldValues: any[]): Query<T>;
  
  /** End results before document snapshot */
  endBefore(snapshot: DocumentSnapshot<any>): Query<T>;
  /** End results before field values */
  endBefore(...fieldValues: any[]): Query<T>;
  
  /** End results at document snapshot */
  endAt(snapshot: DocumentSnapshot<any>): Query<T>;
  /** End results at field values */
  endAt(...fieldValues: any[]): Query<T>;
  
  /** Check if this query equals another */
  isEqual(other: Query<T>): boolean;
  
  /** Execute query and get results */
  get(options?: GetOptions): Promise<QuerySnapshot<T>>;
  
  /** Listen for query result changes */
  onSnapshot(observer: {
    next?: (snapshot: QuerySnapshot<T>) => void;
    error?: (error: FirestoreError) => void;
    complete?: () => void;
  }): () => void;
  onSnapshot(
    options: SnapshotListenOptions,
    observer: {
      next?: (snapshot: QuerySnapshot<T>) => void;
      error?: (error: FirestoreError) => void;
      complete?: () => void;
    }
  ): () => void;
  onSnapshot(
    onNext: (snapshot: QuerySnapshot<T>) => void,
    onError?: (error: FirestoreError) => void,
    onCompletion?: () => void
  ): () => void;
  onSnapshot(
    options: SnapshotListenOptions,
    onNext: (snapshot: QuerySnapshot<T>) => void,
    onError?: (error: FirestoreError) => void,
    onCompletion?: () => void
  ): () => void;
  
  /** Convert this query to use a different data type */
  withConverter(converter: null): Query<DocumentData>;
  withConverter<U>(converter: FirestoreDataConverter<U>): Query<U>;
}

Query Types and Constants

type OrderByDirection = 'desc' | 'asc';

type WhereFilterOp =
  | '<'    // Less than
  | '<='   // Less than or equal
  | '=='   // Equal to
  | '!='   // Not equal to
  | '>='   // Greater than or equal
  | '>'    // Greater than
  | 'array-contains'     // Array contains value
  | 'in'                 // Field value in array
  | 'array-contains-any' // Array contains any of the values
  | 'not-in';            // Field value not in array

FieldPath Class

Type-safe field path construction for nested fields.

class FieldPath {
  /** Create a field path from field names */
  constructor(...fieldNames: string[]);
  
  /** Special field path representing document ID */
  static documentId(): FieldPath;
  
  /** Check if this field path equals another */
  isEqual(other: FieldPath): boolean;
}

Usage Examples

Basic Collection Operations

import type { CollectionReference, DocumentData } from "@firebase/firestore-types";

interface User {
  name: string;
  email: string;
  age: number;
}

async function manageCollection(collection: CollectionReference<User>) {
  // Add new document with auto-generated ID
  const docRef = await collection.add({
    name: "Alice",
    email: "alice@example.com",
    age: 30
  });
  
  // Get specific document reference
  const specificDoc = collection.doc("user-123");
  
  // Get all documents in collection
  const snapshot = await collection.get();
  snapshot.forEach(doc => {
    const userData = doc.data(); // Typed as User
    console.log('User:', userData.name);
  });
}

Query Building

import type { Query, WhereFilterOp, OrderByDirection } from "@firebase/firestore-types";

function buildQueries(usersCollection: CollectionReference<User>) {
  // Simple where clause
  const adults = usersCollection.where("age", ">=", 18);
  
  // Multiple filters
  const activeAdults = usersCollection
    .where("age", ">=", 18)
    .where("status", "==", "active");
  
  // Array queries
  const usersInCities = usersCollection
    .where("city", "in", ["New York", "San Francisco", "Seattle"]);
  
  // Ordering and limiting
  const topUsers = usersCollection
    .orderBy("score", "desc")
    .limit(10);
  
  // Pagination with cursors
  const paginatedQuery = usersCollection
    .orderBy("createdAt")
    .startAfter(lastDocSnapshot)
    .limit(20);
  
  return { adults, activeAdults, usersInCities, topUsers, paginatedQuery };
}

Field Paths for Nested Data

import type { FieldPath } from "@firebase/firestore-types";

interface UserProfile {
  basic: {
    name: string;
    email: string;
  };
  preferences: {
    theme: string;
    notifications: boolean;
  };
}

function queryNestedFields(collection: CollectionReference<UserProfile>) {
  // Query nested field using dot notation
  const darkThemeUsers = collection.where("preferences.theme", "==", "dark");
  
  // Query nested field using FieldPath
  const notificationUsers = collection.where(
    new FieldPath("preferences", "notifications"),
    "==",
    true
  );
  
  // Order by nested field
  const orderedByName = collection.orderBy("basic.name");
  
  return { darkThemeUsers, notificationUsers, orderedByName };
}

Real-time Query Listeners

import type { QuerySnapshot, DocumentChange } from "@firebase/firestore-types";

function listenToQuery(query: Query<User>) {
  const unsubscribe = query.onSnapshot({
    next: (snapshot: QuerySnapshot<User>) => {
      console.log(`Query returned ${snapshot.size} documents`);
      
      // Process changes
      const changes = snapshot.docChanges();
      changes.forEach((change: DocumentChange<User>) => {
        const userData = change.doc.data();
        
        switch (change.type) {
          case 'added':
            console.log('New user:', userData.name);
            break;
          case 'modified':
            console.log('Modified user:', userData.name);
            break;
          case 'removed':
            console.log('Removed user:', userData.name);
            break;
        }
      });
    },
    error: (error) => {
      console.error('Query error:', error);
    }
  });
  
  return unsubscribe;
}

docs

collections-queries.md

core-database.md

data-snapshots.md

data-types.md

document-references.md

index.md

transactions-batches.md

tile.json