Em um ciclo de vida comum, uma função do Firebase Realtime Database faz o seguinte:
- Espera por mudanças em um caminho específico do Realtime Database.
- É acionada quando um evento ocorre e realiza as tarefas dela.
- Recebe um objeto de dados que contém um snapshot dos dados armazenados naquele caminho.
É possível acionar uma função em resposta à gravação, criação, atualização ou exclusão de nós do banco de dados no Firebase Realtime Database.
Acionar uma função quando houver mudanças no Firebase Realtime Database
Use o subpacote firebase-functions/v2/database
para criar uma função que gerencie eventos do Firebase Realtime Database. Para
controlar quando a função é acionada, especifique um dos manipuladores de eventos e
o caminho do Realtime Database em que ela vai detectar os eventos.
Como definir o local da função
A distância entre o local da instância do Realtime Database e o da função pode criar uma latência de rede significativa. Além disso, uma incompatibilidade entre as regiões pode resultar em uma falha na implantação. Para evitar essas situações, especifique o local da função para que ela corresponda ao local da instância do banco de dados.
Processar eventos do Realtime Database
O Functions processa os eventos do Realtime Database em dois níveis de especificidade. É possível detectar especificamente apenas eventos de gravação, criação, atualização ou exclusão, ou detectar alterações de qualquer tipo em uma referência.
Estes gerenciadores de resposta a eventos do Realtime Database estão disponíveis:
onValueWritten()
: acionado apenas quando os dados são gravados no Realtime Database.onValueCreated()
: acionado apenas quando os dados são criados no Realtime Database.onValueUpdated()
: acionado apenas quando os dados são atualizados no Realtime Database.onValueDeleted()
: acionado apenas quando os dados são excluídos no Realtime Database.
Especificar a instância e o caminho
Para controlar quando e onde sua função deve ser acionada, faça a configuração com um caminho e, se preferir, uma instância do Realtime Database. Se você não especificar uma instância, a função será implantada em todas as instâncias do Realtime Database na região da função. Também é possível especificar um padrão de instância do Realtime Database para implantar em um subconjunto seletivo de instâncias na mesma região.
Por exemplo, usando onValueWritten()
:
# 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) => { // … } );
Esses parâmetros direcionam sua função para lidar com as gravações em um determinado caminho na instância do Realtime Database.
As especificações de caminho correspondem a todas as gravações realizadas em um
caminho, incluindo as que ocorrem em qualquer lugar abaixo dele. Se você definir o caminho
para sua função como /foo/bar
, ele vai corresponder aos eventos nestes dois locais:
/foo/bar
/foo/bar/baz/really/deep/path
Em ambos os casos, o Firebase interpreta que o evento ocorre em /foo/bar
,
e os dados do evento incluem os dados antigos e novos em /foo/bar
. Se os dados
do evento forem grandes, considere usar várias funções em caminhos mais profundos em vez
de uma única função próxima à raiz do banco de dados. Para ter o melhor desempenho,
solicite apenas dados no nível mais profundo possível.
Caracteres curinga e captura
Use {key}
, {key=*}
, {key=prefix*}
, {key=*suffix}
para fazer a captura. *
, prefix*
, *suffix
para caracteres curinga em segmento único.
Observação: **
representa caracteres curinga com vários segmentos, que não são compatíveis com RTDB.
Consulte Entender os padrões de caminho.
Caracteres curinga de caminho. É possível especificar um componente de caminho como caractere curinga:
- Usando asterisco,
*
. Por exemplo,foo/*
corresponde a qualquer nível filho da hierarquia de nós abaixo defoo/
. - Usando um segmento que contenha exatamente o asterisco,
*
. Por exemplo:foo/app*-us
corresponde a qualquer segmento filho abaixo defoo/
com o prefixoapp
e o sufixo-us
.
Os caminhos com caracteres curinga podem corresponder a vários eventos, como uma única gravação. Uma inserção de
{
"foo": {
"hello": "world",
"firebase": "functions"
}
}
corresponde ao caminho "/foo/*"
duas vezes: em "hello": "world"
e depois em "firebase": "functions"
.
Captura de caminho. É possível capturar correspondências de caminho em variáveis nomeadas que serão usadas
no seu código de função (por exemplo, /user/{uid}
, /user/{uid=*-us}
).
Os valores das variáveis de captura estão disponíveis no objeto database.DatabaseEvent.params da sua função.
Caracteres curinga de instância. Também é possível especificar um componente de instância
usando caracteres curinga. Um caractere curinga de instância pode ter prefixo, sufixo ou ambos
(por exemplo, my-app-*-prod
).
Referência de caracteres curinga e de captura.
É possível usar um padrão ao
especificar ref
e instance
com o Cloud Functions (2nd gen) e o Realtime Database. Cada interface de gatilho terá as opções
a seguir de escopo de uma função:
Como especificar ref |
Como especificar instance |
Comportamento |
---|---|---|
Única (/foo/bar ) |
Não especificado | Gerenciador de escopos para todas as instâncias na região da função. |
Única (/foo/bar ) |
Única (‘my-new-db' ) |
Gerenciador de escopos da instância específica na região da função. |
Única (/foo/bar ) |
Padrão (‘inst-prefix*' ) |
Gerenciador de escopos para todas as instâncias que correspondem ao padrão na região da função. |
Padrão (/foo/{bar} ) |
Não especificado | Gerenciador de escopos para todas as instâncias na região da função. |
Padrão (/foo/{bar} ) |
Única (‘my-new-db' ) |
Gerenciador de escopos da instância específica na região da função. |
Padrão (/foo/{bar} ) |
Padrão (‘inst-prefix*' ) |
Gerenciador de escopos para todas as instâncias que correspondem ao padrão na região da função. |
Processar dados de eventos
Ao processar um evento do Realtime Database, o objeto de dados retornado é um
DataSnapshot
.
Para eventos onValueWritten
ou onValueUpdated
, o
primeiro parâmetro é um Change
objeto que contém dois snapshots
que representam o estado dos dados antes e depois do evento de acionamento.
Para eventos onValueCreated
e onValueDeleted
,
o objeto de dados retornado é um snapshot dos dados criados ou excluídos.
Neste exemplo, a função recupera o snapshot do
caminho especificado foo/bar
como snap
, converte a string nessa localização para
maiúscula e grava a string modificada no banco de dados:
// 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); });
Como ler o valor anterior
O objeto Change
tem uma propriedade before
que permite inspecionar o que foi
salvo no Realtime Database antes do evento. A propriedade before
retorna um
DataSnapshot
em que todos os métodos (por exemplo,
val()
e
exists()
)
se referem ao valor anterior. Para ler o novo valor mais uma vez, use
o original DataSnapshot
ou leia a
propriedade after
. Essa propriedade em qualquer Change
será outro DataSnapshot
que representa
o estado dos dados depois que o evento aconteceu.
Por exemplo, a propriedade before
pode ser usada para garantir que a função só
transcreva texto em caixa alta quando ele é criado pela primeira vez:
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); });