← blog
Firestore Firebase Indice composito JavaScript SDK v9

Firestore: compound query with multiple filters and composite index

When you filter a Firestore collection with multiple where() conditions combined with orderBy(), Firestore requires a composite index. The console error already includes a link to create it — but you need to know what's happening.

Compound query — SDK v9

firestore-query.js
import {
  getFirestore, collection, query,
  where, orderBy, limit, getDocs
} from 'firebase/firestore';

const db = getFirestore();

/**
 * Recupera le richieste di un operatore degli ultimi N giorni.
 * Questa query richiede un indice composito su:
 *   [operatorId ASC, tipo ASC, timestamp DESC]
 */
async function getRecentRequests(operatorId, giorni = 90) {
  const cutoff = Date.now() - giorni * 24 * 60 * 60 * 1000;

  const q = query(
    collection(db, 'activityLog'),
    where('operatorId', '==', operatorId),
    where('tipo',       'in', ['ferie', 'permesso', 'malattia']),
    where('timestamp',  '>=', cutoff),
    orderBy('timestamp', 'desc'),
    limit(100)
  );

  const snap = await getDocs(q);
  return snap.docs.map(d => ({ id: d.id, ...d.data() }));
}

Typical console error:
FirebaseError: The query requires an index. You can create it here: https://console.firebase.google.com/...

The link in the error goes directly to the index creation page. Click it and wait 1-2 minutes.

How a composite index works

Firestore automatically creates indexes for every individual field. When you combine multiple fields in a query — especially using orderBy() on a different field from the one being filtered — Firestore can't use single-field indexes and requires a composite one covering all fields involved.

Practical rules:

Create the index manually (without waiting for the error)

firestore.indexes.json — deploy con Firebase CLI
{
  "indexes": [
    {
      "collectionGroup": "activityLog",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "operatorId", "order": "ASCENDING"  },
        { "fieldPath": "tipo",       "order": "ASCENDING"  },
        { "fieldPath": "timestamp", "order": "DESCENDING" }
      ]
    }
  ],
  "fieldOverrides": []
}

Recommended strategy: develop locally, let the console error give you the link the first time, click to create the index, then export the config with firebase firestore:indexes and commit it to your project.

Limits to keep in mind

Related article
PWA notification centre: six categories, two databases — Firestore in production
Related article
Custom Firebase e-commerce: Firestore queries for variants, atomic orders and admin panel

When you need a composite index in Firestore

This snippet shows how to build a Firestore query with multiple where() and orderBy() conditions, when Firestore requires a composite index, how to create one, and how to avoid the most common mistakes.

When to use it

When NOT to use it

Alternatives

Common mistakes

Frequently asked questions about Firestore composite indexes

Firestore requires a composite index when a query combines multiple where() conditions on different fields, or where() and orderBy() on different fields: without a dedicated index, Firestore couldn't run the query efficiently.

When the query fails due to a missing index, Firestore returns an error with a direct link to the console that pre-fills the required fields: just follow it and confirm the creation.

Yes, every composite index is updated on every write to the involved fields, slightly increasing the cost and time of write operations: it's therefore worth creating only the indexes you actually need.