← blog
Firestore Firebase Indice composito JavaScript SDK v9

Firestore: query composta con più filtri e indice composito

Quando filtri una collezione Firestore con più condizioni where() combinate a orderBy(), Firestore richiede un indice composito. Il messaggio di errore in console include già il link per crearlo — ma bisogna sapere cosa sta succedendo.

Query composta — 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() }));
}

Errore tipico in console:
FirebaseError: The query requires an index. You can create it here: https://console.firebase.google.com/...

Il link nell'errore porta direttamente alla creazione dell'indice. Cliccalo e attendi 1-2 minuti.

Come funziona un indice composito

Firestore crea automaticamente indici su ogni singolo campo. Quando combini più campi in una query — specialmente con orderBy() su un campo diverso da quello filtrato — Firestore non può usare gli indici singoli e ne richiede uno composito che copra tutti i campi coinvolti.

Regole pratiche:

  • Uguaglianza semplice == su un campo → nessun indice composito
  • Due o più where() su campi diversi → indice composito richiesto
  • where() + orderBy() su campi diversi → indice composito richiesto
  • in, array-contains-any → richiedono indice se combinati con altri filtri

Crea l'indice manualmente (senza aspettare l'errore)

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": []
}

Strategia consigliata: sviluppa in locale, lascia che l'errore in console ti fornisca il link la prima volta, clicca per creare l'indice, poi esporta la configurazione con firebase firestore:indexes e committala nel progetto.

Limiti da tenere a mente

  • Firestore supporta al massimo 200 indici compositi per progetto
  • Una query con in su N valori esegue N sotto-query internamente
  • Non puoi avere due filtri di disuguaglianza (>, <) su campi diversi nella stessa query
  • L'indice impiega 1-3 minuti per diventare attivo — ricarica la pagina dopo la creazione
Articolo correlato
Centro notifiche PWA: sei categorie, due database — Firestore in produzione
Articolo correlato
E-commerce custom su Firebase: query Firestore per varianti, ordini atomici e admin panel