Attivatori di Firebase Realtime Database

Con Cloud Functions, puoi gestire gli eventi in Firebase Realtime Database nello stesso progetto Google Cloud della funzione. Cloud Functions ti consente di eseguire operazioni di database con privilegi amministrativi completi e garantisce che ogni al database viene elaborata singolarmente. Puoi rendere Firebase Realtime modifiche al database tramite SDK Admin Firebase.

In un ciclo di vita tipico, una funzione di Firebase Realtime Database esegue quanto segue:

  1. Attende le modifiche a una determinata località del database.

  2. Si attiva quando si verifica un evento ed esegue le sue attività.

  3. Riceve un oggetto dati che contiene uno snapshot dei dati archiviati documento specificato.

Tipi di evento

Functions consente di gestire gli eventi di database a due livelli di specificità: puoi ascoltare in modo specifico solo gli eventi di creazione, aggiornamento o eliminazione, oppure rilevare qualsiasi cambiamento di qualsiasi tipo in un percorso. Cloud Functions supporta seguenti tipi di eventi per Realtime Database:

Tipo di evento Trigger
providers/google.firebase.database/eventTypes/ref.write Si attiva per qualsiasi evento di mutazione: quando i dati vengono creati, aggiornati o eliminati nel Realtime Database.
providers/google.firebase.database/eventTypes/ref.create (valore predefinito) Si attiva quando vengono creati nuovi dati in Realtime Database.
providers/google.firebase.database/eventTypes/ref.update Si attiva quando i dati vengono aggiornati in Realtime Database.
providers/google.firebase.database/eventTypes/ref.delete Si attiva quando i dati vengono eliminati da Realtime Database.

Specifica il percorso e l'istanza del database

Per controllare quando e dove deve essere attivata la funzione, devi specificare un e specificare facoltativamente un'istanza di database.

Percorso

Le specifiche del percorso corrispondono a tutte le scritture che riguardano un percorso, incluse quelle che avvengono in qualsiasi punto sottostante. Se imposti il percorso della funzione come /foo/bar, corrisponde a eventi che si trovano in entrambe le seguenti località:

 /foo/bar
 /foo/bar/baz/really/deep/path

In entrambi i casi, Firebase interpreta che l'evento si verifica alle ore /foo/bar e i dati sugli eventi includono i dati vecchi e nuovi di /foo/bar. Se i dati sugli eventi grandi, valuta la possibilità di utilizzare più funzioni con percorsi più profondi invece di in prossimità della radice del database. Per ottenere le migliori prestazioni, richiedi solo i dati al livello più profondo possibile.

Puoi specificare un componente del percorso come carattere jolly circondandolo con parentesi graffe; foo/{bar} corrisponde a un qualsiasi elemento secondario di /foo. I valori di questi caratteri jolly i componenti del percorso sono disponibili all'interno dell'oggetto event.params della funzione. In questo esempio, il valore è disponibile come event.params.bar.

I percorsi con caratteri jolly possono corrispondere a più eventi di una singola scrittura. Un inserimento di:

{
  "foo": {
    "hello": "world",
    "firebase": "functions"
  }
}

corrisponde due volte al percorso /foo/{bar}: una con "hello": "world" e di nuovo con "firebase": "functions".

Istanza

Quando utilizzi la console Google Cloud, è necessario specificare l'istanza del database.

Quando utilizzi Google Cloud CLI, l'istanza deve essere specificata come parte della stringa --trigger-resource.

Ad esempio, la query seguente userebbe quanto segue in --trigger-resource stringa:

--trigger-resource projects/_/instances/DATABASE_INSTANCE/refs/PATH

Struttura evento

Quando gestisci un evento di Realtime Database, l'oggetto data contiene due fornite nel formato di oggetti JSON:

  • data: un'istantanea dei dati acquisiti prima dell'evento che che ha attivato la funzione.

  • delta: un'istantanea dei dati acquisiti dopo l'evento che che ha attivato la funzione.

Esempio di codice

Node.js

/**
 * Background Function triggered by a change to a Firebase RTDB reference.
 *
 * @param {!Object} event The Cloud Functions event.
 * @param {!Object} context The Cloud Functions event context.
 */
exports.helloRTDB = (event, context) => {
  const triggerResource = context.resource;

  console.log(`Function triggered by change to: ${triggerResource}`);
  console.log(`Admin?: ${!!context.auth.admin}`);
  console.log('Delta:');
  console.log(JSON.stringify(event.delta, null, 2));
};

Python

import json

def hello_rtdb(data, context):
    """Triggered by a change to a Firebase RTDB reference.
    Args:
        data (dict): The event payload.
        context (google.cloud.functions.Context): Metadata for the event.
    """
    trigger_resource = context.resource

    print("Function triggered by change to: %s" % trigger_resource)
    print("Admin?: %s" % data.get("admin", False))
    print("Delta:")
    print(json.dumps(data["delta"]))

Vai


// Package p contains a Cloud Function triggered by a Firebase Realtime Database
// event.
package p

import (
	"context"
	"fmt"
	"log"

	"cloud.google.com/go/functions/metadata"
)

// RTDBEvent is the payload of a RTDB event.
type RTDBEvent struct {
	Data  interface{} `json:"data"`
	Delta interface{} `json:"delta"`
}

// HelloRTDB handles changes to a Firebase RTDB.
func HelloRTDB(ctx context.Context, e RTDBEvent) error {
	meta, err := metadata.FromContext(ctx)
	if err != nil {
		return fmt.Errorf("metadata.FromContext: %w", err)
	}
	log.Printf("Function triggered by change to: %v", meta.Resource)
	log.Printf("%+v", e)
	return nil
}

Java

import com.google.cloud.functions.Context;
import com.google.cloud.functions.RawBackgroundFunction;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.util.logging.Logger;

public class FirebaseRtdb implements RawBackgroundFunction {
  private static final Logger logger = Logger.getLogger(FirebaseRtdb.class.getName());

  // Use GSON (https://github.com/google/gson) to parse JSON content.
  private static final Gson gson = new Gson();

  @Override
  public void accept(String json, Context context) {
    logger.info("Function triggered by change to: " + context.resource());

    JsonObject body = gson.fromJson(json, JsonObject.class);

    boolean isAdmin = false;
    if (body != null && body.has("auth")) {
      JsonObject authObj = body.getAsJsonObject("auth");
      isAdmin = authObj.has("admin") && authObj.get("admin").getAsBoolean();
    }

    logger.info("Admin?: " + isAdmin);

    if (body != null && body.has("delta")) {
      logger.info("Delta:");
      logger.info(body.get("delta").toString());
    }
  }
}

C#

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using Google.Events.Protobuf.Firebase.Database.V1;
using Microsoft.Extensions.Logging;
using System.Threading;
using System.Threading.Tasks;

namespace FirebaseRtdb;

public class Function : ICloudEventFunction<ReferenceEventData>
{
    private readonly ILogger _logger;

    public Function(ILogger<Function> logger) =>
        _logger = logger;

    public Task HandleAsync(CloudEvent cloudEvent, ReferenceEventData data, CancellationToken cancellationToken)
    {
        _logger.LogInformation("Function triggered by change to {subject}", cloudEvent.Subject);
        _logger.LogInformation("Delta: {delta}", data.Delta);

        // In this example, we don't need to perform any asynchronous operations, so the
        // method doesn't need to be declared async.
        return Task.CompletedTask;
    }
}

Ruby

require "functions_framework"

# Triggered by a change to a Firebase RTDB document.
FunctionsFramework.cloud_event "hello_rtdb" do |event|
  # Event-triggered Ruby functions receive a CloudEvents::Event::V1 object.
  # See https://cloudevents.github.io/sdk-ruby/latest/CloudEvents/Event/V1.html
  # The Firebase event payload can be obtained from the `data` field.
  payload = event.data

  logger.info "Function triggered by change to: #{event.source}"
  logger.info "Admin?: #{payload.fetch 'admin', false}"
  logger.info "Delta: #{payload['delta']}"
end

PHP


use Google\CloudFunctions\CloudEvent;

function firebaseRTDB(CloudEvent $cloudevent)
{
    $log = fopen(getenv('LOGGER_OUTPUT') ?: 'php://stderr', 'wb');

    fwrite($log, 'Event: ' . $cloudevent->getId() . PHP_EOL);

    $data = $cloudevent->getData();
    $resource = $data['resource'] ?? '<null>';

    fwrite($log, 'Function triggered by change to: ' . $resource . PHP_EOL);

    $isAdmin = isset($data['auth']['admin']) && $data['auth']['admin'] == true;

    fwrite($log, 'Admin?: ' . var_export($isAdmin, true) . PHP_EOL);
    fwrite($log, 'Delta: ' . json_encode($data['delta'] ?? '') . PHP_EOL);
}

esegui il deployment della funzione

Il seguente comando gcloud esegue il deployment di una funzione che verrà attivata dal create eventi nel percorso /messages/{pushId}/original:

gcloud functions deploy FUNCTION_NAME \
  --entry-point ENTRY_POINT \
  --trigger-event providers/google.firebase.database/eventTypes/ref.create \
  --trigger-resource projects/_/instances/DATABASE_INSTANCE/refs/messages/{pushId}/original \
  --runtime RUNTIME
Argomento Descrizione
FUNCTION_NAME Il nome registrato della Cloud Function di cui esegui il deployment. Può essere il nome di una funzione nel del codice sorgente o una stringa arbitraria. Se FUNCTION_NAME è un stringa arbitraria, devi includere Flag --entry-point.
--entry-point ENTRY_POINT Il nome di una funzione o classe nel codice sorgente. Facoltativo, a meno che non hai utilizzato FUNCTION_NAME per specificare nel codice sorgente da eseguire durante il deployment. In questo devi utilizzare --entry-point per indicare il nome del una funzione eseguibile.
--trigger-event NAME Il nome del tipo di evento che la funzione vuole ricevere. In questo caso, sarà uno dei seguenti: scrittura, creazione, aggiornamento o eliminazione.
--trigger-resource NAME Il percorso completo del database in cui la funzione rimane in ascolto. Deve rispettare il seguente formato: projects/_/instances/DATABASE_INSTANCE/refs/PATH.
--runtime RUNTIME Il nome del runtime che stai utilizzando. Per un elenco completo, vedi Riferimento gcloud.