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
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:
- Simple equality
==on one field → no composite index needed - Two or more
where()on different fields → composite index required where()+orderBy()on different fields → composite index requiredin,array-contains-any→ require an index when combined with other filters
Create the index manually (without waiting for the error)
{
"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
- Firestore supports a maximum of 200 composite indexes per project
- A query with
inon N values runs N sub-queries internally - You can't have two inequality filters (
>,<) on different fields in the same query - The index takes 1-3 minutes to become active — reload the page after creation