MotorSignal-App/.claude/skills/firebase-firestore/references/standard/indexes.md

4.4 KiB

Firestore Indexes Reference

Indexes allow Firestore to ensure that query performance depends on the size of the result set, not the size of the database.

Index Types

Single-Field Indexes

In Standard Edition, Firestore automatically creates a single-field index for every field in a document (and subfields in maps). * Support: Simple equality queries (==) and single-field range/sort queries (<, <=, orderBy). * Behavior: You generally don't need to manage these unless you want to exempt a field.

Composite Indexes

A composite index stores a sorted mapping of all documents based on an ordered list of fields. * Support: Complex queries that filter or sort by multiple fields. * Creation: These are NOT automatically created. You must define them manually or via the console/CLI.

Automatic vs. Manual Management

What is Automatic?

  • Indexes for simple queries.
  • Merging of single-field indexes for multiple equality filters (e.g., where("state", "==", "CA").where("country", "==", "USA")).

When Do I Need to Act?

If you attempt a query that requires a composite index, the SDK will throw an error containing a direct link to the Firebase Console to create that specific index.

Example Error:

"The query requires an index. You can create it here: https://console.firebase.google.com/project/..."

Query Support Examples

Query Type Index Required
Simple Equality
`where("a",
Automatic (Single-Field)
: "==", 1)` : :
Simple Range/Sort
`where("a",
Automatic (Single-Field)
: ">", 1).orderBy("a")` : :
Multiple Equality
`where("a",
Automatic (Merged Single-Field)
: "==", 1).where("b", "==", 2)` : :
**Equality + Composite Index
: Range/Sort**
`where("a", "==", : :
: 1).where("b", ">", 2)` : :
Multiple Ranges
`where("a",
Composite Index (and technically
: ">", 1).where("b", ">", 2)` : limited query support) :
**Array Contains + Composite Index
: Equality**
`where("tags", : :
: "array-contains", : :
: "news").where("active", "==", true)` : :

Best Practices & Exemptions

You can exempt fields from automatic indexing to save storage or strictly enforce write limits.

1. High Write Rates (Sequential Values)

  • Problem: Indexing fields that increase sequentially (like timestamp) limits the write rate to ~500 writes/second per collection.
  • Solution: If you don't query on this field, exempt it from simple indexing.

2. Large String/Map/Array Fields

  • Problem: Indexing limits (40k entries per doc). Indexing large blobs wastes storage.
  • Solution: Exempt large text blobs or huge arrays if they aren't used for filtering.

3. TTL Fields

  • Problem: TTL (Time-To-Live) deletion can cause index churn.
  • Solution: Exempt the TTL timestamp field from indexing if you don't query it.

Management

Config files

Your indexes should be defined in firestore.indexes.json (pointed to by firebase.json).

{
  "indexes": [
    {
      "collectionGroup": "cities",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "country", "order": "ASCENDING" },
        { "fieldPath": "population", "order": "DESCENDING" }
      ]
    }
  ],
  "fieldOverrides": []
}

CLI Commands

Deploy indexes only: bash npx -y firebase-tools@latest deploy --only firestore:indexes