Durante lo sviluppo dell'app, potrebbe essere opportuno bloccare l'accesso ai tuoi Cloud Firestore database. Tuttavia, prima del lancio, avrai bisogno di informazioni Cloud Firestore Security Rules. Con l'emulatore Cloud Firestore, oltre a creare prototipi e testare le funzionalità e il comportamento generali della tua app, puoi scrivere test di unità che controllano il comportamento del tuo Cloud Firestore Security Rules.
Guida rapida
Per alcuni casi di test di base con regole semplici, prova l'esempio di avvio rapido.
Informazioni su Cloud Firestore Security Rules
Implementa Firebase Authentication e Cloud Firestore Security Rules per l'autenticazione, l'autorizzazione e la convalida dei dati serverless quando utilizzi le librerie client web e per dispositivi mobili.
Cloud Firestore Security Rules sono costituiti da due parti:
- Un'istruzione
match
che identifica i documenti nel database. - Un'espressione
allow
che controlla l'accesso a questi documenti.
Firebase Authentication verifica l'identità credenziali e fornisce le basi sistemi di accesso basati su utenti e ruoli.
Ogni richiesta di database da una libreria client mobile/web Cloud Firestore viene valutato in base alle regole di sicurezza prima di leggere o scrivere dati. Se le regole negano l'accesso a uno qualsiasi dei percorsi dei documenti specificati, l'intera non va a buon fine.
Scopri di più su Cloud Firestore Security Rules in Iniziare a utilizzare Cloud Firestore Security Rules.
Installa l'emulatore
Per installare l'emulatore Cloud Firestore, utilizza Firebase CLI ed esegui questo comando:
firebase setup:emulators:firestore
Esegui l'emulatore
Inizia inizializzando un progetto Firebase nella directory di lavoro. Si tratta di un primo passaggio comune quando utilizzi l'interfaccia a riga di comando di Firebase.
firebase init
Avvia l'emulatore utilizzando il seguente comando. L'emulatore eseguirà finché il processo non termina:
firebase emulators:start --only firestore
In molti casi si desidera avviare l'emulatore, eseguire una suite di test e quindi chiudere
l'emulatore dopo l'esecuzione dei test. Puoi farlo facilmente utilizzando
Comando emulators:exec
:
firebase emulators:exec --only firestore "./my-test-script.sh"
All'avvio, l'emulatore tenterà di funzionare su una porta predefinita (8080). Puoi
cambia la porta dell'emulatore modificando la sezione "emulators"
del tuo
firebase.json
file:
{ // ... "emulators": { "firestore": { "port": "YOUR_PORT" } } }
Prima di eseguire l'emulatore
Prima di iniziare a utilizzare l'emulatore, tieni presente quanto segue:
- L'emulatore caricherà inizialmente le regole specificate nel campo
firestore.rules
campo del tuo filefirebase.json
. Aspetta il nome di un file locale contenente il tuo Cloud Firestore Security Rules e applica queste regole a tutti i progetti. Se non fornisci il percorso file locale o utilizzi il comandoloadFirestoreRules
come descritto di seguito, l'emulatore tratta tutti progetti con regole aperte. - Anche se
la maggior parte degli SDK di Firebase
funziona direttamente con gli emulatori, solo la libreria
@firebase/rules-unit-testing
supporta la simulazione diauth
nelle regole di sicurezza, semplificando notevolmente i test di unità. Inoltre, la libreria supporta alcune funzioni specifiche dell'emulatore, come la cancellazione di tutti i dati, come indicato di seguito. - Gli emulatori accetteranno anche i token di autenticazione Firebase di produzione forniti tramite SDK client e valutano di conseguenza le regole, il che consente la connessione la tua applicazione direttamente agli emulatori nei test di integrazione e manuali.
Esecuzione dei test delle unità locali
Esecuzione dei test delle unità locali con l'SDK JavaScript v9
Firebase distribuisce una libreria di test delle unità di Regole di sicurezza sia con la relativa versione SDK JavaScript 9 e versione 8 dell'SDK. Le API della libreria sono significativamente diverso. Consigliamo la libreria di test v9, che è più semplice e richiede meno configurazione per connettersi agli emulatori e quindi evita all'uso delle risorse di produzione. Per garantire la compatibilità con le versioni precedenti, la libreria di test v8 disponibile.
- Metodi di test comuni e funzioni di utilità nell'SDK v9
- Metodi di test specifici dell'emulatore nell'SDK v9
Usa il modulo @firebase/rules-unit-testing
per interagire con l'emulatore
eseguito in locale. Se visualizzi timeout o ECONNREFUSED
errori, ricontrolla
che l'emulatore è effettivamente in esecuzione.
Ti consigliamo vivamente di utilizzare una versione recente di Node.js in modo da poter utilizzare
Notazione async/await
. Quasi tutti i comportamenti che potresti voler testare richiedono funzioni asincrone e il modulo di test è progettato per funzionare con il codice basato su promesse.
La libreria di test delle unità delle regole v9 è sempre a conoscenza degli emulatori e non le risorse di produzione.
Puoi importare la libreria utilizzando le istruzioni di importazione modulari v9. Ad esempio:
import {
assertFails,
assertSucceeds,
initializeTestEnvironment
} from "@firebase/rules-unit-testing"
// Use `const { … } = require("@firebase/rules-unit-testing")` if imports are not supported
// Or we suggest `const testing = require("@firebase/rules-unit-testing")` if necessary.
Dopo l'importazione, l'implementazione dei test delle unità comporta:
- Creazione e configurazione di un
RulesTestEnvironment
con una chiamata ainitializeTestEnvironment
. - Configurare i dati di test senza attivare le regole, per praticità
che ti consente di ignorarli temporaneamente,
RulesTestEnvironment.withSecurityRulesDisabled
. - Configurazione di suite di test e hook prima/dopo per test con chiamate per pulizia dei dati e dell'ambiente di test, ad esempio
RulesTestEnvironment.cleanup()
oRulesTestEnvironment.clearFirestore()
. - Implementazione di scenari di test che imitano gli stati di autenticazione utilizzando
RulesTestEnvironment.authenticatedContext
eRulesTestEnvironment.unauthenticatedContext
.
Metodi comuni e funzioni di utilità
Vedi anche i metodi di test specifici dell'emulatore nell'SDK v9.
initializeTestEnvironment() => RulesTestEnvironment
Questa funzione inizializza un ambiente di test per il test delle unità di regole. Chiama per la configurazione di test. Per una corretta esecuzione è necessario che gli emulatori in esecuzione.
La funzione accetta un oggetto facoltativo che definisce un valore TestEnvironmentConfig
,
che può essere composto da un ID progetto e dalle impostazioni di configurazione dell'emulatore.
let testEnv = await initializeTestEnvironment({ projectId: "demo-project-1234", firestore: { rules: fs.readFileSync("firestore.rules", "utf8"), }, });
RulesTestEnvironment.authenticatedContext({ user_id: string, tokenOptions?: TokenOptions }) => RulesTestContext
Questo metodo crea un RulesTestContext
, che si comporta come un utente autenticato
Utente autenticazione. Le richieste create tramite il contesto restituito avranno una simulazione
Token di autenticazione collegato. Se vuoi, passa un oggetto che definisce rivendicazioni personalizzate
per i payload dei token di autenticazione.
Utilizza l'oggetto contesto test restituito nei test per accedere a eventuali istanze di emulatore configurate, incluse quelle configurate con initializeTestEnvironment
.
// Assuming a Firestore app and the Firestore emulator for this example import { setDoc } from "firebase/firestore"; const alice = testEnv.authenticatedContext("alice", { … }); // Use the Firestore instance associated with this context await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
RulesTestEnvironment.unauthenticatedContext() => RulesTestContext
Questo metodo crea un RulesTestContext
, che si comporta come un client che
non hanno effettuato l'accesso tramite Authentication. Le richieste create tramite il contesto restituito
collegati dei token di autenticazione Firebase.
Utilizza l'oggetto contesto test restituito nei test per accedere a eventuali istanze di emulatore configurate, incluse quelle configurate con initializeTestEnvironment
.
// Assuming a Cloud Storage app and the Storage emulator for this example import { getStorage, ref, deleteObject } from "firebase/storage"; const alice = testEnv.unauthenticatedContext(); // Use the Cloud Storage instance associated with this context const desertRef = ref(alice.storage(), 'images/desert.jpg'); await assertSucceeds(deleteObject(desertRef));
RulesTestEnvironment.withSecurityRulesDisabled()
Esegui una funzione di configurazione di test con un contesto che si comporti come se le regole di sicurezza fossero disattivata.
Questo metodo accetta una funzione di callback, che accetta il contesto di aggiramento delle regole di sicurezza e restituisce una promessa. Il contesto verrà distrutto una volta che la promessa risolve / rifiuta.
RulesTestEnvironment.cleanup()
Questo metodo elimina tutti i RulesTestContexts
creati nell'ambiente di test e pulizia delle risorse sottostanti, consentendo un'uscita pulita.
Questo metodo non modifica in alcun modo lo stato degli emulatori. Per reimpostare i dati tra i test, usa il metodo dei dati in chiaro specifico dell'emulatore di applicazioni.
assertSucceeds(pr: Promise<any>)) => Promise<any>
Questa è una funzione di utilità per i casi di test.
La funzione asserisce che la Promise fornita che aggrega un'operazione dell'emulatore verrà risolta senza violazioni delle regole di sicurezza.
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
Questa è una funzione di utilità per i casi di test.
La funzione asserisce che la Promise fornita che aggrega un'operazione dell'emulatore verranno rifiutate con una violazione delle Regole di sicurezza.
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
Metodi specifici dell'emulatore
Consulta anche i metodi di test e le funzioni di utilità comuni nell'SDK versione 9.
RulesTestEnvironment.clearFirestore() => Promise<void>
Questo metodo cancella i dati nel database Firestore che appartiene al
projectId
configurato per l'emulatore Firestore.
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
Questo metodo ottiene un'istanza Firestore per il contesto di test. L'oggetto restituito L'istanza SDK client JS di Firebase può essere utilizzata con le API SDK client (v9 modulare o v9).
Visualizzare le valutazioni delle regole
L'emulatore Cloud Firestore ti consente di visualizzare le richieste del client l'interfaccia utente di Emulator Suite, con il tracciamento della valutazione per le regole di sicurezza di Firebase.
Apri Firestore > Richieste per visualizzare la valutazione dettagliata una sequenza per ogni richiesta.
Genera report sui test
Dopo aver eseguito una suite di test, puoi accedere e report sulla copertura che mostrano come è stata valutata ciascuna delle tue regole di sicurezza.
Per ottenere i report, esegui una query su un endpoint esposto sull'emulatore sia in esecuzione. Per una versione ottimizzata per il browser, utilizza il seguente URL:
http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage.html
In questo modo, le regole vengono suddivise in espressioni e sottoespressioni su cui puoi eseguire il passaggio del mouse per visualizzare ulteriori informazioni, tra cui il numero di valutazioni e i valori restituiti. Per la versione JSON non elaborata di questi dati, includi il seguente URL nella tua query:
http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage
Differenze tra emulatore e produzione
- Non è necessario creare esplicitamente un progetto Cloud Firestore. L'emulatore crea automaticamente qualsiasi istanza a cui viene eseguito l'accesso.
- L'emulatore Cloud Firestore non funziona con il normale flusso Firebase Authentication.
Nell'SDK Firebase Test abbiamo invece fornito il metodo
initializeTestApp()
nellarules-unit-testing
, che richiede un campoauth
. L'handle Firebase è stato creato questo metodo si comporterà come se l'autenticazione sia riuscita indipendentemente dall'entità che fornisci. Se lo superi innull
, si comporterà come un utente non autenticato (ad esempio,auth != null
regole non andranno a buon fine).
Risolvere i problemi noti
Quando utilizzi l'emulatore Cloud Firestore, potresti riscontrare quanto segue che le applicazioni presentino problemi di prestazioni. Segui le indicazioni riportate di seguito per risolvere i tuoi comportamenti irregolari in cui ti trovi. Queste note sono scritte con il test dell'unità Regole di sicurezza ma gli approcci generali sono applicabili a qualsiasi SDK Firebase.
Il comportamento del test non è coerente
Se occasionalmente i test non vanno a buon fine, anche senza alcuna modifica alle
potrebbe essere necessario verificare che siano sequenziati correttamente.
La maggior parte delle interazioni con l'emulatore è asincrona, quindi verifica che tutte
il codice asincrono sia sequenziato correttamente. Puoi correggere la sequenzialità concatenando le promesse o utilizzando liberamente la notazione await
.
In particolare, esamina le seguenti operazioni asincrone:
- Impostazione di regole di sicurezza, con, ad esempio,
initializeTestEnvironment
. - Lettura e scrittura di dati, ad esempio con
db.collection("users").doc("alice").get()
. - Affermazioni operative, tra cui
assertSucceeds
eassertFails
.
I test passano solo la prima volta che carichi l'emulatore
L'emulatore è stateful. Tutti i dati scritti vengono memorizzati in memoria, ogni volta che l'emulatore si arresta vengono persi i dati. Se esegui più test sullo stesso ID progetto, ogni test può produrre dati che potrebbero influire sui test successivi. Per ignora questo comportamento:
- Utilizza ID progetto univoci per ogni test. Tieni presente che, se scegli questa opzione,
dovrà chiamare
initializeTestEnvironment
nell'ambito di ogni test; regole vengono caricati automaticamente solo per l'ID progetto predefinito. - Ristruttura i test in modo che non interagiscano con dati scritti in precedenza (ad esempio, utilizza una raccolta diversa per ogni test).
- Elimina tutti i dati scritti durante un test.
La configurazione del test è molto complicata
Quando configuri il test, potresti voler modificare i dati in un modo che Cloud Firestore Security Rules non consente. Se le regole eseguono la configurazione di prova
complesso, prova a usare RulesTestEnvironment.withSecurityRulesDisabled
nella configurazione
passaggi, quindi le operazioni di lettura e scrittura non attiveranno PERMISSION_DENIED
errori.
In seguito, il test potrà eseguire operazioni come autenticazione
utente che utilizza RulesTestEnvironment.authenticatedContext
e unauthenticatedContext
rispettivamente. In questo modo puoi verificare che Cloud Firestore Security Rules consenta o rifiuti
casi diversi.