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 unitari per la tua app che convalidano il tuo Rules.
Se non l'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
ostorage.rules
del filefirebase.json
. Se il file non esiste e non utilizzi il metodoloadFirestoreRules
oloadStorageRules
come descritto di seguito, l'emulatore considera tutti i progetti come se avessero regole aperte. - Sebbene
la maggior parte degli SDK Firebase
funzioni direttamente con gli emulatori, solo la libreria
@firebase/rules-unit-testing
supporta la simulazioneauth
nelle regole di sicurezza, semplificando notevolmente i test unitari. Inoltre, la libreria supporta alcune funzionalità specifiche dell'emulatore, come la cancellazione di tutti i dati, come elencato di seguito. - Gli emulatori accettano anche i token di Firebase Auth di produzione forniti tramite gli SDK client e valutano le regole di conseguenza, il che consente di connettere l'applicazione direttamente agli emulatori nei test di integrazione e manuali.
Differenze tra gli emulatori di database e la produzione
- Non devi creare esplicitamente un'istanza di database. L'emulatore creerà automaticamente qualsiasi istanza del database a cui viene eseguito l'accesso.
- Ogni nuovo database viene avviato con regole chiuse, quindi gli utenti non amministratori non potranno leggere o scrivere.
- Ogni database emulato applica i limiti e le quote del piano Spark (in particolare, questo limita ogni istanza a 100 connessioni simultanee).
- Qualsiasi database accetterà la stringa
"owner"
come token di autenticazione amministratore. - Al momento gli emulatori non interagiscono 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 l'autenticazione fosse stata eseguita correttamente come qualsiasi entità fornita. Se trasmettinull
, il comportamento sarà quello di un utente non autenticato (ad esempio, le regoleauth != null
non andranno a buon fine).
Interazione con l'emulatore Realtime Database
Un'istanza Firebase Realtime Database di produzione è accessibile a un sottodominio di
firebaseio.com
e puoi accedere all'API REST nel seguente modo:
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 di database specifica, devi utilizzare il parametro di query ns
per specificare il nome del database.
http://localhost:9000/path/to/my/data.json?ns=<database_name>
Esegui test locali delle unità con la versione 9 dell'SDK JavaScript
Firebase distribuisce una libreria di unit test delle regole di sicurezza sia con l'SDK JavaScript versione 9 sia con l'SDK versione 8. Le API della libreria sono molto diverse. Ti consigliamo la libreria di test v9, che è più snella e richiede meno configurazione per connettersi agli emulatori ed evitare così in modo sicuro l'uso accidentale di risorse di produzione. Per la compatibilità con le versioni precedenti, continuiamo a rendere disponibile la libreria di test v8.
- Metodi di test e funzioni di utilità comuni nell'SDK v9
- Metodi di test specifici dell'emulatore nell'SDK v9
Utilizza il modulo @firebase/rules-unit-testing
per interagire con l'emulatore
che viene 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 tutto il comportamento che potresti voler testare
riguarda le 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 tocca mai le risorse di produzione.
Importa la libreria utilizzando le istruzioni di importazione modulare 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.
Una volta importati, l'implementazione dei test delle unità prevede:
- Creazione e configurazione di un
RulesTestEnvironment
con una chiamata ainitializeTestEnvironment
. - Configurazione di dati di test senza attivare Rules, utilizzando un metodo pratico che consente di aggirarli temporaneamente,
RulesTestEnvironment.withSecurityRulesDisabled
. - Configurazione della suite di test e degli hook pre/post test con chiamate per
pulire i dati e l'ambiente di test, ad esempio
RulesTestEnvironment.cleanup()
oRulesTestEnvironment.clearFirestore()
. - Implementazione di scenari di test che simulano gli stati di autenticazione utilizzando
RulesTestEnvironment.authenticatedContext
eRulesTestEnvironment.unauthenticatedContext
.
Metodi comuni e funzioni di utilità
Vedi anche Metodi di test specifici dell'emulatore che utilizzano l'API modulare.
initializeTestEnvironment() => RulesTestEnvironment
Questa funzione inizializza un ambiente di test per il test delle unità delle regole. Chiama questa funzione per prima per la configurazione del test. L'esecuzione corretta richiede l'esecuzione degli emulatori.
La funzione accetta un oggetto facoltativo che definisce un TestEnvironmentConfig
,
che può essere costituito 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 Authentication autenticato. Le richieste create tramite il contesto restituito avranno un token
Authentication allegato. Se vuoi, passa un oggetto che definisce rivendicazioni personalizzate o
override per i payload dei token Authentication.
Utilizza l'oggetto contesto di test restituito nei test per accedere a qualsiasi istanza dell'emulatore configurata, 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 di test restituito nei test per accedere a qualsiasi istanza dell'emulatore configurata, 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 disattivate.
Questo metodo accetta una funzione di callback, che accetta il contesto di bypass delle regole di sicurezza e restituisce una promessa. Il contesto verrà eliminato una volta che la promessa viene risolta / rifiutata.
RulesTestEnvironment.cleanup()
Questo metodo elimina tutti i RulesTestContexts
creati nell'ambiente di test e
pulisce le risorse sottostanti, consentendo un'uscita pulita.
Questo metodo non modifica in alcun modo lo stato degli emulatori. Per reimpostare i dati tra i test, 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 asserisce che la promessa 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 asserisce che la promessa 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 dell'emulatore
Consulta anche i metodi di test e le 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 di Firestore per questo contesto di test. L'istanza dell'SDK client Firebase JS restituita può essere utilizzata con le API dell'SDK client (modulare v9 o compatibilità v9).
Realtime Database
Realtime Database
RulesTestEnvironment.clearDatabase() => Promise<void>
Questo metodo cancella i dati in Realtime Database appartenenti a
projectId
configurato per l'emulatore Realtime Database.
RulesTestContext.database(databaseURL?: Firestore.FirestoreSettings) => Firestore;
Ottieni un'istanza Realtime Database per questo contesto di test. L'istanza dell'SDK client Firebase JS restituita può essere utilizzata con le API dell'SDK client (modulare o con spazi dei nomi, versione 9 o successive). Il metodo accetta un URL dell'istanza Realtime Database. Se specificato, restituisce un'istanza per una versione emulata dello spazio dei nomi con 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 a
projectId
configurato per l'emulatore Cloud Storage.
RulesTestContext.storage(bucketUrl?: string) => Firebase Storage;
Questo metodo restituisce un'istanza Storage configurata per connettersi all'emulatore.
Il metodo accetta un URL gs://
al bucket Firebase Storage per il test. Se
specificato, restituisce un'istanza Storage per una versione emulata del nome del bucket.
Esegui test delle unità locali con l'SDK JavaScript v8
Seleziona un prodotto per visualizzare i metodi utilizzati dall'SDK Firebase Test per interfacciarsi 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 specificati 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 operazioni di lettura e scrittura. Utilizza questo comando 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 amministrative attualmente inizializzate.
Utilizza questo comando per pulire le app tra un test e l'altro 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 in locale. 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 che viene rifiutata se l'input ha esito positivo o che ha esito positivo se l'input viene rifiutato. Utilizza questo metodo 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. Utilizza questo metodo per verificare se una lettura o scrittura del database va 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 in locale. Utilizza questo metodo per eseguire 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 auth specificato nelle opzioni.
firebase.initializeTestApp({
databaseName: "my-database",
auth: { uid: "alice" }
});
initializeAdminApp({ databaseName: string }) => FirebaseApp
Utilizza questo strumento per creare un'app autenticata come amministratore per configurare lo stato dei test.
Restituisce un'app Firebase di amministrazione inizializzata corrispondente al nome del database specificato nelle opzioni. Questa app ignora le regole di sicurezza durante la lettura e la scrittura nel database.
firebase.initializeAdminApp({ databaseName: "my-database" });
loadDatabaseRules({ databaseName: string, rules: Object }) => Promise
Utilizza questa opzione per impostare le regole del database.
Invia le regole a un database in esecuzione locale. Accetta un oggetto di 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 amministrazione attualmente inizializzate.
Utilizza questo comando per pulire le app tra un test e l'altro o dopo i test (tieni presente che le app inizializzate con listener attivi impediscono l'uscita di JavaScript):
Promise.all(firebase.apps().map(app => app.delete()))
assertFails(pr: Promise) => Promise
Restituisce una promessa che viene rifiutata se l'input ha esito positivo e ha esito positivo se l'input viene rifiutato.
Utilizza questo metodo per verificare che una lettura o scrittura del 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 questo comando per verificare che una lettura o scrittura del database vada 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 all'override della variabile di autenticazione specificato nelle opzioni.
firebase.initializeTestApp({
storageBucket: "my-bucket",
auth: { uid: "alice" }
});
initializeAdminApp({ storageBucket: string }) => FirebaseApp
Utilizza questo strumento per creare un'app autenticata come amministratore per configurare lo stato dei test.
Restituisce un'app Firebase di amministrazione inizializzata corrispondente al nome del bucket di archiviazione specificato nelle opzioni. Questa app ignora 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. Accetta un oggetto di opzioni 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 amministrazione attualmente inizializzate.
Utilizza questo comando per pulire le app tra un test e l'altro o dopo i test (tieni presente che le app inizializzate con listener attivi impediscono l'uscita di JavaScript):
Promise.all(firebase.apps().map(app => app.delete()))
assertFails(pr: Promise) => Promise
Restituisce una promessa che viene rifiutata se l'input ha esito positivo e ha esito positivo se l'input viene rifiutato.
Utilizza questo comando per verificare che una lettura o scrittura del 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 comando per verificare che la lettura o la scrittura di un bucket di archiviazione vada 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 Firebase Test per interfacciarsi 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 specificati 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 operazioni di lettura e scrittura. Utilizza questo comando 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 amministrative attualmente inizializzate.
Utilizza questo comando per pulire le app tra un test e l'altro 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 in locale. 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 che viene rifiutata se l'input ha esito positivo o che ha esito positivo se l'input viene rifiutato. Utilizza questo metodo 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. Utilizza questo metodo per verificare se una lettura o scrittura del database va 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 in locale. Utilizza questo metodo per eseguire 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 auth specificato nelle opzioni.
firebase.initializeTestApp({
databaseName: "my-database",
auth: { uid: "alice" }
});
initializeAdminApp({ databaseName: string }) => FirebaseApp
Utilizza questo strumento per creare un'app autenticata come amministratore per configurare lo stato dei test.
Restituisce un'app Firebase di amministrazione inizializzata corrispondente al nome del database specificato nelle opzioni. Questa app ignora le regole di sicurezza durante la lettura e la scrittura nel database.
firebase.initializeAdminApp({ databaseName: "my-database" });
loadDatabaseRules({ databaseName: string, rules: Object }) => Promise
Utilizza questa opzione per impostare le regole del database.
Invia le regole a un database in esecuzione locale. Accetta un oggetto di 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 amministrazione attualmente inizializzate.
Utilizza questo comando per pulire le app tra un test e l'altro o dopo i test (tieni presente che le app inizializzate con listener attivi impediscono l'uscita di JavaScript):
Promise.all(firebase.apps().map(app => app.delete()))
assertFails(pr: Promise) => Promise
Restituisce una promessa che viene rifiutata se l'input ha esito positivo e ha esito positivo se l'input viene rifiutato.
Utilizza questo metodo per verificare che una lettura o scrittura del 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 questo comando per verificare che una lettura o scrittura del database vada 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 all'override della variabile di autenticazione specificato nelle opzioni.
firebase.initializeTestApp({
storageBucket: "my-bucket",
auth: { uid: "alice" }
});
initializeAdminApp({ storageBucket: string }) => FirebaseApp
Utilizza questo strumento per creare un'app autenticata come amministratore per configurare lo stato dei test.
Restituisce un'app Firebase di amministrazione inizializzata corrispondente al nome del bucket di archiviazione specificato nelle opzioni. Questa app ignora 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. Accetta un oggetto di opzioni 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 amministrazione attualmente inizializzate.
Utilizza questo comando per pulire le app tra un test e l'altro o dopo i test (tieni presente che le app inizializzate con listener attivi impediscono l'uscita di JavaScript):
Promise.all(firebase.apps().map(app => app.delete()))
assertFails(pr: Promise) => Promise
Restituisce una promessa che viene rifiutata se l'input ha esito positivo e ha esito positivo se l'input viene rifiutato.
Utilizza questo comando per verificare che una lettura o scrittura del 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 comando per verificare che la lettura o la scrittura di un bucket di archiviazione vada a buon fine:
firebase.assertFails(app.storage().ref("images/cat.png").getMetadata());