Firebase Local Emulator Suite semplificano la convalida completa delle funzionalità e del comportamento della tua app. È anche un ottimo strumento per verificare le configurazioni di Firebase Security Rules. Utilizza gli emulatori Firebase per eseguire e automatizzare i test delle unità in un ambiente locale. I metodi descritti in questo documento dovrebbero aiutarti a creare e automatizzare i test di unità per la tua app che convalidano il tuo Rules.
Se non lo hai ancora fatto, configura gli emulatori Firebase.
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
o "storage.rules" del filefirebase.json
. Se il file non esiste e non utilizzi il metodoloadFirestoreRules
o "loadStorageRules" come descritto di seguito, l'emulatore considera tutti i progetti come contenenti regole aperte. - Anche se la maggior parte degli SDK Firebase funziona direttamente con gli emulatori, solo la libreria
@firebase/rules-unit-testing
supporta ilauth
simulato nelle regole di sicurezza, semplificando notevolmente i test di unità. Inoltre, la libreria supporta alcune funzionalità specifiche dell'emulatore, come l'eliminazione di tutti i dati, come elencato di seguito. - Gli emulatori accetteranno anche i token di produzione di Firebase Authentication forniti tramite gli SDK client e valuteranno le regole di conseguenza, il che consente di collegare la tua applicazione direttamente agli emulatori nei test di integrazione e manuali.
Differenze tra gli emulatori di database e la produzione
- Non è necessario creare esplicitamente un'istanza di database. L'emulatore creerà automaticamente qualsiasi istanza di database a cui viene eseguito l'accesso.
- Ogni nuovo database viene avviato con regole chiuse, pertanto gli utenti non amministratori non potranno leggere né scrivere.
- A ogni database simulato vengono applicati i limiti e le quote del piano Spark (in particolare, ogni istanza è limitata a 100 connessioni simultanee).
- Qualsiasi database accetterà la stringa
"owner"
come token di autenticazione amministratore. - Al momento gli emulatori non hanno interazioni funzionanti con altri prodotti Firebase. In particolare, il normale flusso di Firebase Authentication non funziona.
In alternativa, puoi utilizzare il metodo
initializeTestApp()
nella libreriarules-unit-testing
, che accetta un campoauth
. L'oggetto Firebase creato utilizzando questo metodo si comporta come se fosse stato autenticato correttamente come qualsiasi entità fornita. Se passinull
, il valore si comporterà come un utente non autenticato (ad esempio, le regoleauth != null
non andranno a buon fine).
Interazione con l'emulatore Realtime Database
Un'istanza Realtime Database Firebase di produzione è accessibile da un sottodominio di
firebaseio.com
e puoi accedere all'API REST come segue:
https://<database_name>.firebaseio.com/path/to/my/data.json
L'emulatore viene eseguito localmente ed è disponibile all'indirizzo localhost:9000
. Per interagire con un'istanza del database specifica, dovrai utilizzare il parametro di query ns
per specificare il nome del database.
http://localhost:9000/path/to/my/data.json?ns=<database_name>
Eseguire test locali delle unità con l'SDK JavaScript versione 9
Firebase distribuisce una libreria di test di unità delle regole di sicurezza sia con l'SDK JavaScript di versione 9 sia con l'SDK di versione 8. Le API della libreria sono molto diverse. Consigliamo la libreria di test v9, che è più snella e richiede meno configurazione per connettersi agli emulatori e quindi evitare in modo sicuro l'uso accidentale delle risorse di produzione. Per la compatibilità con le versioni precedenti, continuiamo a mettere a disposizione la libreria di test v8.
- Metodi di test e funzioni di utilità comuni nell'SDK versione 9
- Metodi di test specifici per l'emulatore nell'SDK v9
Utilizza il modulo @firebase/rules-unit-testing
per interagire con l'emulatore eseguito localmente. Se si verificano timeout o errori ECONNREFUSED
, verifica che l'emulatore sia effettivamente in esecuzione.
Ti consigliamo vivamente di utilizzare una versione recente di Node.js per poter utilizzare la 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 9 è sempre consapevole degli emulatori e non tocca mai le risorse di produzione.
Importa la libreria utilizzando le istruzioni di importazione modulari della versione 9. 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.
Una volta importati, l'implementazione dei test di unità prevede:
- Creazione e configurazione di un
RulesTestEnvironment
con una chiamata ainitializeTestEnvironment
. - Configurare i dati di test senza attivare Rules, utilizzando un metodo di comodità che consente di ignorarli temporaneamente,
RulesTestEnvironment.withSecurityRulesDisabled
. - Configurazione di suite di test e hook prima/dopo per test con chiamate per pulizia dell'ambiente e dei dati di test, ad esempio
RulesTestEnvironment.cleanup()
oRulesTestEnvironment.clearFirestore()
. - Implementazione di casi di test che simulano gli stati di autenticazione utilizzando
RulesTestEnvironment.authenticatedContext
eRulesTestEnvironment.unauthenticatedContext
.
Metodi e funzioni di utilità comuni
Consulta anche metodi di test specifici per l'emulatore che utilizzano l'API modulare.
initializeTestEnvironment() => RulesTestEnvironment
Questa funzione inizializza un ambiente di test per i test delle unità delle regole. Chiama innanzitutto questa funzione per la configurazione del test. Per un'esecuzione corretta è necessario che gli emulatori siano in esecuzione.
La funzione accetta un oggetto facoltativo che definisce un TestEnvironmentConfig
,
che può essere costituito da un ID progetto e da 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 Authentication autenticato. Alle richieste create tramite il contesto restituito verrà allegato un token Authentication simulato. Se vuoi, puoi passare un oggetto che definisce rivendicazioni personalizzate o superamenti per i payload dei token Authentication.
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 ha eseguito l'accesso tramite Authentication. Le richieste create tramite il contesto restituito non
avranno token Firebase Auth allegati.
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 del test con un contesto che si comporta come se le Regole di sicurezza fossero disabilitate.
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 viene risolta / rifiutata.
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 un test e l'altro, utilizza il metodo di cancellazione dei dati specifico dell'emulatore dell'applicazione.
assertSucceeds(pr: Promise<any>)) => Promise<any>
Questa è una funzione di utilità per i casi di test.
La funzione afferma che la Promise fornita che racchiude 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 afferma che la Promise fornita che racchiude un'operazione dell'emulatore verrà rifiutata con una violazione delle regole di sicurezza.
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
Metodi specifici per l'emulatore
Consulta anche metodi di test e funzioni di utilità comuni che utilizzano l'API modulare.
Cloud Firestore
Cloud Firestore
RulesTestEnvironment.clearFirestore() => Promise<void>
Questo metodo cancella i dati nel database Firestore appartenenti al
projectId
configurato per l'emulatore Firestore.
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
Questo metodo recupera un'istanza Firestore per questo contesto di test. L'istanza dell'SDK client Firebase JS restituita può essere utilizzata con le API SDK client (v9 modulare o v9 compatibile).
Realtime Database
Realtime Database
RulesTestEnvironment.clearDatabase() => Promise<void>
Questo metodo cancella i dati in Realtime Database che appartengono al
projectId
configurato per l'emulatore Realtime Database.
RulesTestContext.database(databaseURL?: Firestore.FirestoreSettings) => Firestore;
Recupera un'istanza di Realtime Database per questo contesto di test. L'istanza dell'SDK client Firebase JS restituita può essere utilizzata con le API dell'SDK client (modulari o con nome, versione 9 o successive). Il metodo accetta un URL dell'istanza Database in tempo reale. Se specificato, restituisce un'istanza per una versione emulata dello spazio dei nomi con i parametri estratti dall'URL.
Cloud Storage
Cloud Storage
RulesTestEnvironment.clearStorage() => Promise<void>
Questo metodo cancella gli oggetti e i metadati nei bucket di archiviazione appartenenti al
projectId
configurato per l'emulatore Cloud Storage.
RulesTestContext.storage(bucketUrl?: string) => Firebase Storage;
Questo metodo restituisce un'istanza di Storage configurata per connettersi all'emulatore.
Il metodo accetta un URL gs://
al bucket Firebase Storage per i test. Se specificato, restituisce un'istanza Storage per una versione emulata del nome del bucket.
Eseguire test locali delle unità con l'SDK JavaScript v8
Seleziona un prodotto per visualizzare i metodi utilizzati dall'SDK di test di Firebase per interagire con l'emulatore.
Cloud Firestore
initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp
Questo metodo restituisce un'app Firebase inizializzata corrispondente all'ID progetto e alla variabile di autenticazione specificata nelle opzioni. Utilizzalo per creare un'app autenticata come utente specifico da utilizzare nei test.
firebase.initializeTestApp({ projectId: "my-test-project", auth: { uid: "alice", email: "alice@example.com" } });
initializeAdminApp({ projectId: string }) => FirebaseApp
Questo metodo restituisce un'app Firebase di amministrazione inizializzata. Questa app ignora le regole di sicurezza durante l'esecuzione di letture e scritture. Utilizzalo per creare un'app autenticata come amministratore per impostare lo stato per i test.
firebase.initializeAdminApp({ projectId: "my-test-project" });
apps() => [FirebaseApp]
Questo metodo restituisce tutte le app di test e di amministrazione attualmente inizializzate.
Utilizzalo per ripulire le app tra o dopo i test.
Promise.all(firebase.apps().map(app => app.delete()))
loadFirestoreRules({ projectId: string, rules: Object }) => Promise
Questo metodo invia le regole a un database in esecuzione localmente. Prende un oggetto che specifica le regole come stringa. Utilizza questo metodo per impostare le regole del database.
firebase.loadFirestoreRules({ projectId: "my-test-project", rules: fs.readFileSync("/path/to/firestore.rules", "utf8") });
assertFails(pr: Promise) => Promise
Questo metodo restituisce una promessa rifiutata se l'input va a buon fine o che va a buon fine se l'input viene rifiutato. Utilizzalo per verificare se una lettura o scrittura del database non va a buon fine.
firebase.assertFails(app.firestore().collection("private").doc("super-secret-document").get());
assertSucceeds(pr: Promise) => Promise
Questo metodo restituisce una promessa che ha esito positivo se l'input ha esito positivo e viene rifiutata se l'input viene rifiutato. Utilizzalo per verificare se una lettura o scrittura del database è andata a buon fine.
firebase.assertSucceeds(app.firestore().collection("public").doc("test-document").get());
clearFirestoreData({ projectId: string }) => Promise
Questo metodo cancella tutti i dati associati a un determinato progetto nell'istanza Firestore in esecuzione localmente. Utilizza questo metodo per la pulizia dopo i test.
firebase.clearFirestoreData({ projectId: "my-test-project" });
Realtime Database
Realtime Database
initializeTestApp({ databaseName: string, auth: Object }) => FirebaseApp
Utilizzalo per creare un'app autenticata come utente specifico da utilizzare nei test.
Restituisce un'app Firebase inizializzata corrispondente al nome del database e all'override della variabile di autenticazione specificata in options.
firebase.initializeTestApp({
databaseName: "my-database",
auth: { uid: "alice" }
});
initializeAdminApp({ databaseName: string }) => FirebaseApp
Utilizzalo per creare un'app autenticata come amministratore per configurare lo stato per i test.
Restituisce un'app Firebase di amministrazione inizializzata corrispondente al nome del database specificato in options. Questa app aggira le regole di sicurezza durante la lettura e la scrittura nel database.
firebase.initializeAdminApp({ databaseName: "my-database" });
loadDatabaseRules({ databaseName: string, rules: Object }) => Promise
Utilizzalo per impostare le regole del database.
Invia le regole a un database in esecuzione localmente. Accetta un oggetto opzioni che specifica "databaseName" e "rules" come stringhe.
firebase
.loadDatabaseRules({
databaseName: "my-database",
rules: "{'rules': {'.read': false, '.write': false}}"
});
apps() => [FirebaseApp]
Restituisce tutte le app di test e di amministrazione attualmente inizializzate.
Utilizza questo metodo per ripulire le app tra o dopo i test (tieni presente che le app inizializzate con ascoltatori attivi impediscono a JavaScript di uscire):
Promise.all(firebase.apps().map(app => app.delete()))
assertFails(pr: Promise) => Promise
Restituisce una promessa rifiutata se l'input va a buon fine e accolta se l'input viene rifiutato.
Utilizza questa istruzione per verificare che la lettura o la scrittura di un database non vada a buon fine:
firebase.assertFails(app.database().ref("secret").once("value"));
assertSucceeds(pr: Promise) => Promise
Restituisce una promessa che ha esito positivo se l'input ha esito positivo e viene rifiutata se l'input viene rifiutato.
Utilizza questa istruzione per verificare che una lettura o scrittura del database sia andata a buon fine:
firebase.assertSucceeds(app.database().ref("public").once("value"));
Cloud Storage
Cloud Storage
initializeTestApp({ storageBucket: string, auth: Object }) => FirebaseApp
Utilizzalo per creare un'app autenticata come utente specifico da utilizzare nei test.
Restituisce un'app Firebase inizializzata corrispondente al nome del bucket di archiviazione e alla sostituzione della variabile di autenticazione specificata nelle opzioni.
firebase.initializeTestApp({
storageBucket: "my-bucket",
auth: { uid: "alice" }
});
initializeAdminApp({ storageBucket: string }) => FirebaseApp
Utilizzalo per creare un'app autenticata come amministratore per configurare lo stato per i test.
Restituisce un'app Firebase di amministrazione inizializzata corrispondente al nome del bucket di archiviazione specificato in options. Questa app aggira le regole di sicurezza durante la lettura e la scrittura nel bucket.
firebase.initializeAdminApp({ storageBucket: "my-bucket" });
loadStorageRules({ storageBucket: string, rules: Object }) => Promise
Utilizzalo per impostare le regole del bucket di archiviazione.
Invia regole a bucket di archiviazione gestiti localmente. Prende un oggetto options che specifica "storageBucket" e "rules" come stringhe.
firebase
.loadStorageRules({
storageBucket: "my-bucket",
rules: fs.readFileSync("/path/to/storage.rules", "utf8")
});
apps() => [FirebaseApp]
Restituisce tutte le app di test e di amministrazione attualmente inizializzate.
Utilizza questo metodo per ripulire le app tra o dopo i test (tieni presente che le app inizializzate con ascoltatori attivi impediscono a JavaScript di uscire):
Promise.all(firebase.apps().map(app => app.delete()))
assertFails(pr: Promise) => Promise
Restituisce una promessa rifiutata se l'input va a buon fine e accolta se l'input viene rifiutato.
Utilizza questo parametro per verificare che la lettura o la scrittura di un bucket di archiviazione non vada a buon fine:
firebase.assertFails(app.storage().ref("letters/private.doc").getMetadata());
assertSucceeds(pr: Promise) => Promise
Restituisce una promessa che ha esito positivo se l'input ha esito positivo e viene rifiutata se l'input viene rifiutato.
Utilizza questo metodo per verificare che la lettura o la scrittura di un bucket di archiviazione sia andata a buon fine:
firebase.assertFails(app.storage().ref("images/cat.png").getMetadata());
API della libreria RUT per JS SDK v8
Seleziona un prodotto per visualizzare i metodi utilizzati dall'SDK di test di Firebase per interagire con l'emulatore.
Cloud Firestore
Cloud Firestore
initializeTestApp({ projectId: string, auth: Object }) => FirebaseApp
Questo metodo restituisce un'app Firebase inizializzata corrispondente all'ID progetto e alla variabile di autenticazione specificata nelle opzioni. Utilizzalo per creare un'app autenticata come utente specifico da utilizzare nei test.
firebase.initializeTestApp({ projectId: "my-test-project", auth: { uid: "alice", email: "alice@example.com" } });
initializeAdminApp({ projectId: string }) => FirebaseApp
Questo metodo restituisce un'app Firebase di amministrazione inizializzata. Questa app ignora le regole di sicurezza durante l'esecuzione di letture e scritture. Utilizzalo per creare un'app autenticata come amministratore per impostare lo stato per i test.
firebase.initializeAdminApp({ projectId: "my-test-project" });
apps() => [FirebaseApp]
Questo metodo restituisce tutte le app di test e di amministrazione attualmente inizializzate.
Utilizzalo per ripulire le app tra o dopo i test.
Promise.all(firebase.apps().map(app => app.delete()))
loadFirestoreRules({ projectId: string, rules: Object }) => Promise
Questo metodo invia le regole a un database in esecuzione localmente. Prende un oggetto che specifica le regole come stringa. Utilizza questo metodo per impostare le regole del database.
firebase.loadFirestoreRules({ projectId: "my-test-project", rules: fs.readFileSync("/path/to/firestore.rules", "utf8") });
assertFails(pr: Promise) => Promise
Questo metodo restituisce una promessa rifiutata se l'input va a buon fine o che va a buon fine se l'input viene rifiutato. Utilizzalo per verificare se una lettura o scrittura del database non va a buon fine.
firebase.assertFails(app.firestore().collection("private").doc("super-secret-document").get());
assertSucceeds(pr: Promise) => Promise
Questo metodo restituisce una promessa che ha esito positivo se l'input ha esito positivo e viene rifiutata se l'input viene rifiutato. Utilizzalo per verificare se una lettura o scrittura del database è andata a buon fine.
firebase.assertSucceeds(app.firestore().collection("public").doc("test-document").get());
clearFirestoreData({ projectId: string }) => Promise
Questo metodo cancella tutti i dati associati a un determinato progetto nell'istanza Firestore in esecuzione localmente. Utilizza questo metodo per la pulizia dopo i test.
firebase.clearFirestoreData({ projectId: "my-test-project" });
Realtime Database
Realtime Database
initializeTestApp({ databaseName: string, auth: Object }) => FirebaseApp
Utilizzalo per creare un'app autenticata come utente specifico da utilizzare nei test.
Restituisce un'app Firebase inizializzata corrispondente al nome del database e all'override della variabile di autenticazione specificata in options.
firebase.initializeTestApp({
databaseName: "my-database",
auth: { uid: "alice" }
});
initializeAdminApp({ databaseName: string }) => FirebaseApp
Utilizzalo per creare un'app autenticata come amministratore per configurare lo stato per i test.
Restituisce un'app Firebase di amministrazione inizializzata corrispondente al nome del database specificato in options. Questa app aggira le regole di sicurezza durante la lettura e la scrittura nel database.
firebase.initializeAdminApp({ databaseName: "my-database" });
loadDatabaseRules({ databaseName: string, rules: Object }) => Promise
Utilizzalo per impostare le regole del database.
Invia le regole a un database in esecuzione localmente. Accetta un oggetto opzioni che specifica "databaseName" e "rules" come stringhe.
firebase
.loadDatabaseRules({
databaseName: "my-database",
rules: "{'rules': {'.read': false, '.write': false}}"
});
apps() => [FirebaseApp]
Restituisce tutte le app di test e di amministrazione attualmente inizializzate.
Utilizza questo metodo per ripulire le app tra o dopo i test (tieni presente che le app inizializzate con ascoltatori attivi impediscono a JavaScript di uscire):
Promise.all(firebase.apps().map(app => app.delete()))
assertFails(pr: Promise) => Promise
Restituisce una promessa rifiutata se l'input va a buon fine e accolta se l'input viene rifiutato.
Utilizza questa istruzione per verificare che la lettura o la scrittura di un database non vada a buon fine:
firebase.assertFails(app.database().ref("secret").once("value"));
assertSucceeds(pr: Promise) => Promise
Restituisce una promessa che ha esito positivo se l'input ha esito positivo e viene rifiutata se l'input viene rifiutato.
Utilizza questa istruzione per verificare che una lettura o scrittura del database sia andata a buon fine:
firebase.assertSucceeds(app.database().ref("public").once("value"));
Cloud Storage
Cloud Storage
initializeTestApp({ storageBucket: string, auth: Object }) => FirebaseApp
Utilizzalo per creare un'app autenticata come utente specifico da utilizzare nei test.
Restituisce un'app Firebase inizializzata corrispondente al nome del bucket di archiviazione e alla sostituzione della variabile di autenticazione specificata nelle opzioni.
firebase.initializeTestApp({
storageBucket: "my-bucket",
auth: { uid: "alice" }
});
initializeAdminApp({ storageBucket: string }) => FirebaseApp
Utilizzalo per creare un'app autenticata come amministratore per configurare lo stato per i test.
Restituisce un'app Firebase di amministrazione inizializzata corrispondente al nome del bucket di archiviazione specificato in options. Questa app aggira le regole di sicurezza durante la lettura e la scrittura nel bucket.
firebase.initializeAdminApp({ storageBucket: "my-bucket" });
loadStorageRules({ storageBucket: string, rules: Object }) => Promise
Utilizzalo per impostare le regole del bucket di archiviazione.
Invia regole a bucket di archiviazione gestiti localmente. Prende un oggetto options che specifica "storageBucket" e "rules" come stringhe.
firebase
.loadStorageRules({
storageBucket: "my-bucket",
rules: fs.readFileSync("/path/to/storage.rules", "utf8")
});
apps() => [FirebaseApp]
Restituisce tutte le app di test e di amministrazione attualmente inizializzate.
Utilizza questo metodo per ripulire le app tra o dopo i test (tieni presente che le app inizializzate con ascoltatori attivi impediscono a JavaScript di uscire):
Promise.all(firebase.apps().map(app => app.delete()))
assertFails(pr: Promise) => Promise
Restituisce una promessa rifiutata se l'input va a buon fine e accolta se l'input viene rifiutato.
Utilizza questo parametro per verificare che la lettura o la scrittura di un bucket di archiviazione non vada a buon fine:
firebase.assertFails(app.storage().ref("letters/private.doc").getMetadata());
assertSucceeds(pr: Promise) => Promise
Restituisce una promessa che ha esito positivo se l'input ha esito positivo e viene rifiutata se l'input viene rifiutato.
Utilizza questo metodo per verificare che la lettura o la scrittura di un bucket di archiviazione sia andata a buon fine:
firebase.assertFails(app.storage().ref("images/cat.png").getMetadata());