In un tipico ciclo di vita, una funzione Firebase Realtime Database esegue le seguenti operazioni:
- Attende le modifiche a un particolare percorso del database in tempo reale.
- Si attiva quando si verifica un evento e ne esegue le attività.
- Riceve un oggetto dati che contiene uno snapshot dei dati archiviati in tale percorso.
Puoi attivare una funzione in risposta alla scrittura, creazione, aggiornamento o eliminazione di nodi di database in Firebase Realtime Database.
Attiva una funzione sulle modifiche al database in tempo reale di Firebase
Utilizza il sottopacchetto firebase-functions/v2/database
per creare una funzione che gestisca gli eventi di Firebase Realtime Database. Per controllare quando la funzione si attiva, specificare uno dei gestori di eventi e specificare il percorso del database in tempo reale in cui ascolterà gli eventi.
Impostazione della posizione della funzione
La distanza tra la posizione di un'istanza di Realtime Database e la posizione della funzione può creare una significativa latenza di rete. Inoltre, una mancata corrispondenza tra le regioni può causare un errore di distribuzione. Per evitare queste situazioni, specificare il percorso della funzione in modo che corrisponda al percorso dell'istanza del database .
Gestione degli eventi del database in tempo reale
Le funzioni consentono di gestire gli eventi di Realtime Database a due livelli di specificità; puoi ascoltare in modo specifico solo gli eventi di scrittura, creazione, aggiornamento o eliminazione oppure puoi ascoltare qualsiasi modifica di qualsiasi tipo a un riferimento.
Sono disponibili questi gestori per rispondere agli eventi di Realtime Database:
-
onValueWritten()
Attivato solo quando i dati vengono scritti in Realtime Database. -
onValueCreated()
Attivato solo quando i dati vengono creati in Realtime Database. -
onValueUpdated()
Attivato solo quando i dati vengono aggiornati in Realtime Database. -
onValueDeleted()
Attivato solo quando i dati vengono eliminati in Realtime Database.
Specificare istanza e percorso
Per controllare quando e dove la tua funzione dovrebbe attivarsi, configura la tua funzione con un percorso e facoltativamente un'istanza di Realtime Database. Se non si specifica un'istanza, la funzione viene distribuita a tutte le istanze di Realtime Database nell'area della funzione. Puoi anche specificare un modello di istanza di Realtime Database da distribuire a un sottoinsieme selettivo di istanze nella stessa regione.
Ad esempio, utilizzando onValueWritten()
per l'illustrazione:
# All Realtime Database instances in default function region us-central1 at path "/user/{uid}" # There must be at least one Realtime Database present in us-central1. const onwrittenfunctiondefault = onValueWritten("/user/{uid}", (event) => { // … }); # Instance named "my-app-db-2", at path "/user/{uid}". # The "my-app-db-2" instance must exist in this region. const onwrittenfunctioninstance = onValueWritten( { ref: "/user/{uid}", instance: "my-app-db-2" // This example assumes us-central1, but to set location: // region: "europe-west1" }, (event) => { // … } ); # Instance with "my-app-db-" prefix, at path "/user/{uid}", where uid ends with @gmail.com. # There must be at least one Realtime Database with "my-app-db-*" prefix in this region. const onwrittenfunctioninstance = onValueWritten( { ref: "/user/{uid=*@gmail.com}", instance: "my-app-db-*" // This example assumes us-central1, but to set location: // region: "europe-west1" }, (event) => { // … } );
Questi parametri indirizzano la tua funzione a gestire le scritture in un determinato percorso all'interno dell'istanza di Realtime Database.
Le specifiche del percorso corrispondono a tutte le scritture che toccano un percorso, comprese le scritture che si verificano ovunque al di sotto di esso. Se imposti il percorso per la tua funzione come /foo/bar
, corrisponde agli eventi in entrambe queste posizioni:
/foo/bar
/foo/bar/baz/really/deep/path
In entrambi i casi, Firebase interpreta che l'evento si verifica in /foo/bar
e i dati dell'evento includono i dati vecchi e nuovi in /foo/bar
. Se i dati dell'evento potrebbero essere di grandi dimensioni, prendere in considerazione l'utilizzo di più funzioni in percorsi più profondi invece di una singola funzione vicino alla radice del database. Per le migliori prestazioni, richiedi solo i dati al livello più profondo possibile.
Caratteri jolly e cattura
Puoi usare {key}
, {key=*}
, {key=prefix*}
, {key=*suffix}
per l'acquisizione. *
, prefix*
, *suffix
per caratteri jolly a segmento singolo. Nota: **
rappresenta i caratteri jolly multisegmento, che RTDB non supporta. Vedere Comprendere i modelli di percorso .
Caratteri jolly del percorso. È possibile specificare un componente del percorso come carattere jolly:
- Usando l'asterisco,
*
. Ad esempio,foo/*
corrisponde a qualsiasi figlio di un livello della gerarchia dei nodi al di sottofoo/
. - Utilizzando un segmento contenente esattamente un asterisco,
*
. Ad esempio,foo/app*-us
corrisponde a qualsiasi segmento figlio sottofoo/
con prefissoapp
e suffisso-us
.
I percorsi con caratteri jolly possono corrispondere a più eventi, ad esempio, da una singola scrittura. Un inserto di
{
"foo": {
"hello": "world",
"firebase": "functions"
}
}
corrisponde al percorso "/foo/*"
due volte: una volta con "hello": "world"
e di nuovo con "firebase": "functions"
.
Acquisizione del percorso. È possibile acquisire le corrispondenze del percorso in variabili denominate da utilizzare nel codice della funzione (ad esempio /user/{uid}
, /user/{uid=*-us}
).
I valori delle variabili di acquisizione sono disponibili all'interno dell'oggetto database.DatabaseEvent.params della funzione.
Caratteri jolly di istanza. È inoltre possibile specificare un componente dell'istanza utilizzando i caratteri jolly. Un carattere jolly di istanza può avere prefisso, suffisso o entrambi (ad esempio my-app-*-prod
).
Carattere jolly e riferimento all'acquisizione
Con Cloud Functions (2a generazione) e Realtime Database, è possibile utilizzare un pattern quando si specifica ref
e instance
. Ogni interfaccia trigger avrà le seguenti opzioni per l'ambito di una funzione:
Specificando ref | Specificare instance | Comportamento |
---|---|---|
Singolo ( /foo/bar ) | Non specificando | Gestore degli ambiti per tutte le istanze nell'area della funzione. |
Singolo ( /foo/bar ) | Singolo ( 'my-new-db' ) | Gestore degli ambiti all'istanza specifica nell'area della funzione. |
Singolo ( /foo/bar ) | Schema ( 'inst-prefix*' ) | Gestore degli ambiti per tutte le istanze che corrispondono al modello nell'area della funzione. |
Modello ( /foo/{bar} ) | Non specificando | Gestore degli ambiti per tutte le istanze nell'area della funzione. |
Modello ( /foo/{bar} ) | Singolo ( 'my-new-db' ) | Gestore degli ambiti all'istanza specifica nell'area della funzione. |
Modello ( /foo/{bar} ) | Schema ( 'inst-prefix*' ) | Gestore degli ambiti per tutte le istanze che corrispondono al modello nell'area della funzione. |
Gestire i dati dell'evento
Quando si gestisce un evento Realtime Database, l'oggetto dati restituito è un DataSnapshot
.
Per gli eventi onValueWritten
o onValueUpdated
, il primo parametro è un oggetto Change
che contiene due snapshot che rappresentano lo stato dei dati prima e dopo l'evento di attivazione.
Per gli eventi onValueCreated
e onValueDeleted
, l'oggetto dati restituito è uno snapshot dei dati creati o eliminati.
In questo esempio, la funzione recupera lo snapshot per il percorso specificato foo/bar
come snap
, converte la stringa in quella posizione in maiuscolo e scrive quella stringa modificata nel database:
// Listens for new messages added to /messages/:pushId/original and creates an // uppercase version of the message to /messages/:pushId/uppercase export makeuppercase = onValueCreated("foo/bar", (event) => { // Grab the current value of what was written to the Realtime Database. const original = event.data.val(); functions.logger.log('Uppercasing', event.params.pushId, original); const uppercase = original.toUpperCase(); // You must return a Promise when performing asynchronous tasks inside a Functions such as // writing to the Firebase Realtime Database. // Setting an "uppercase" sibling in the Realtime Database returns a Promise. return event.data.ref.parent.child('uppercase').set(uppercase); });
Lettura del valore precedente
L'oggetto Change
ha una proprietà before
che consente di ispezionare cosa è stato salvato in Realtime Database prima dell'evento. La proprietà before
restituisce un DataSnapshot
in cui tutti i metodi (ad esempio, val()
ed exists()
) fanno riferimento al valore precedente. È possibile leggere nuovamente il nuovo valore utilizzando il DataSnapshot
originale o leggendo la proprietà after
. Questa proprietà su qualsiasi Change
è un altro DataSnapshot
che rappresenta lo stato dei dati dopo che si è verificato l'evento.
Ad esempio, la proprietà before
può essere utilizzata per assicurarsi che la funzione scriva solo lettere maiuscole quando viene creata per la prima volta:
exports makeuppercase = onValueWritten("/messages/{pushId}/original", (event) => { // Only edit data when it is first created. if (event.data.before.exists()) { return null; } // Exit when the data is deleted. if (!event.data.after.exists()) { return null; } // Grab the current value of what was written to the Realtime Database. const original = event.data.after.val(); console.log('Uppercasing', event.params.pushId, original); const uppercase = original.toUpperCase(); // You must return a Promise when performing asynchronous tasks inside a Functions such as // writing to the Firebase Realtime Database. // Setting an "uppercase" sibling in the Realtime Database returns a Promise. return event.data.after.ref.parent.child('uppercase').set(uppercase); });