Extend Data Connect with Cloud Functions Stay organized with collections Save and categorize content based on your preferences.
WithCloud Functions for Firebase, you can handle events inFirebase Data Connect.Cloud Functions lets you run server-side code inresponse to events, such as the execution of a mutation in yourData Connect service. This lets you add custom logic withoutdeploying your own servers.
Common use cases
Data Synchronization: Replicate or synchronize data with other systems(likeCloud Firestore, BigQuery, or external APIs) after a mutationoccurs.
Asynchronous Workflows: Kick off long-running processes, such as imageprocessing or data aggregation, after a database change.
User engagement: Send emails orCloud Messaging notifications tousers after a specific mutation event in your application, such as accountcreation.
Trigger a function on aData Connect mutation
You can trigger a function whenever aData Connect mutation is executedusing theonMutationExecuted event handler. This trigger occurs upon executionof amutation.
A basic mutation event function
The following basic example is a function that logs the details ofany mutation executed in yourData Connect service:
Node.js
import{onMutationExecuted}from"firebase-functions/dataconnect";import{logger}from"firebase-functions";exportconstlogMutation=onMutationExecuted({/* Trigger on all mutations, spanning all services and connectors in us-central1 */},(event)=>{logger.info("A mutation was executed!",{data:event.data,});});Python
fromfirebase_functionsimportdataconnect_fn,logger@dataconnect_fn.on_mutation_executed()deflog_mutation(event:dataconnect_fn.Event):logger.info("A mutation was executed!",event.data)When triggering off of all mutations in your project, you must not perform anymutations in the trigger handler or you will cause an infinite loop. If you wantto perform mutations in an event trigger, use the filtering options describedbelow, and take care that the mutation does not trigger itself.
Set the function location
Thefunction location must match theData Connect service locationfor events to trigger the function. By default, the function region isus-central1.
Node.js
import{onMutationExecuted}from"firebase-functions/dataconnect";exportconstonMutationRegionOption=onMutationExecuted({region:"europe-west1"// Set ifData Connect service location is not us-central1},(event)=>{/* ... */});Python
@dataconnect_fn.on_mutation_executed(region="europe-west1"# Set ifData Connect service location is not us-central1)defmutation_executed_handler_region_option(event:dataconnect_fn.Event):passFilter events
TheonMutationExecuted handler can be configured with options to filter eventsbased on specific attributes. This is useful when you only want to trigger yourfunction for certain mutations.
You can filter byservice,connector, andoperation:
Node.js
import{onMutationExecuted}from"firebase-functions/dataconnect";import{logger}from"firebase-functions";// Trigger this function only for the CreateUser mutation// in the users connector of the myAppService service.exportconstonUserCreate=onMutationExecuted({service:"myAppService",connector:"users",operation:"CreateUser",},(event)=>{logger.info("A new user was created!",event.data);// Add logic here: for example, sending a welcome email.});Python
fromfirebase_functionsimportdataconnect_fn,logger@dataconnect_fn.on_mutation_executed(service="myAppService",connector="users",operation="CreateUser"):defon_user_create(event:dataconnect_fn.Event):logger.info("A new user was created!",event.data)Wildcards and capture groups
You can use wildcards and capture groups to filter your triggers on multiplevalues. Any groups captured are availableinevent.params to use. SeeUnderstand path patternsfor more information.
Examples:
Node.js
import{onMutationExecuted}from"firebase-functions/dataconnect";// Trigger on all operations that match the pattern `User*`, on any service and// connector.exportconstonMutationWildcards=onMutationExecuted({operation:"User*",},(event)=>{});// Trigger on all operations that match the pattern `User*`, on any service and// connector. Capture the operation name in the variable `op`.exportconstonMutationCaptureWildcards=onMutationExecuted({operation:"{op=User*}",},(event)=>{// `event.params.op` contains the operation name.});// Trigger on all operations on the service `myAppService`. Capture the// operation name in the variable `operation`.exportconstonMutationCaptures=onMutationExecuted({service:"myAppService",operation:"{operation}",},(event)=>{// `event.params.operation` contains the operation name.});Python
fromfirebase_functionsimportdataconnect_fn# Trigger on all operations that match the pattern `User*`, on any service and# connector.@dataconnect_fn.on_mutation_executed(operation="User*")defon_mutation_wildcards(event:dataconnect_fn.Event):pass# Trigger on all operations that match the pattern `User*`, on any service and# connector. Capture the operation name in the variable `op`.@dataconnect_fn.on_mutation_executed(operation="{op=User*}")defon_mutation_capture_wildcards(event:dataconnect_fn.Event):# `event.params["op"]` contains the operation name.pass# Trigger on all operations on the service `myAppService`. Capture the# operation name in the variable `operation`.@dataconnect_fn.on_mutation_executed(service="myAppService",operation="{operation}")defon_mutation_captures(event:dataconnect_fn.Event):# `event.params["operation"]` contains the operation name.passAccess user authentication information
You can access user authentication information about the principal thattriggered the event. For more information about the data available in theauthentication context, seeAuth Context.
The following example demonstrates how to retrieve authentication information:
Node.js
import{onMutationExecuted}from"firebase-functions/dataconnect";exportconstonMutation=onMutationExecuted({operation:"MyMutation"},(event)=>{// mutationExecuted event provides authType and authId:// event.authType// event.authId});Python
fromfirebase_functionsimportdataconnect_fn@dataconnect_fn.on_mutation_executed(operation="MyMutation")defmutation_executed_handler(event:dataconnect_fn.Event):# mutationExecuted event provides auth_type and auth_id, which are accessed as follows# event.auth_type# event.auth_idpassThe auth type and auth ID will be populated as such:
| Mutation initiated by | authtype | authid |
|---|---|---|
| Authenticated end user | app_user | Firebase Auth token UID |
| Unauthenticated end user | unauthenticated | empty |
| Admin SDK impersonating an end user | app_user | Firebase Auth token UID of the impersonated user |
| Admin SDK impersonating an unauthenticated request | unauthenticated | empty |
| Admin SDK with full permissions | admin | empty |
Access event data
TheCloudEvent object passed to your function contains information about theevent that triggered it.
Event attributes
| Attribute | Type | Description |
|---|---|---|
id | string | A unique identifier for the event. |
source | string | The connector resource that produced the event (for example,//firebasedataconnect.googleapis.com/projects/*/locations/*/services/*/connectors/*). |
specversion | string | TheCloudEvents specification version (e.g., "1.0"). |
type | string | The type of the event:google.firebase.dataconnect.connector.v1.mutationExecuted. |
time | string | The timestamp (ISO 8601 format) for when the event was produced. |
subject | string | Optional. Extra information about the event context, like the operation name. |
params | object | A map of captured path patterns. |
authType | string | An enum representing the type of principal that triggered the event. |
authId | string | A unique identifier of the principal that triggered the event. |
data | MutationEventData | The payload of theData Connect event. See the next section. |
Data payload
TheMutationEventData object contains the payload of theData Connect event:
{// ..."authType":// ..."data":{"payload":{"variables":{"userId":"user123","updateData":{"displayName":"New Name"}},"data":{"updateUser":{"id":"user123","displayName":"New Name","email":"user@example.com"}},"errors":[]}}}payload.variables: An object containing the variables that werepassed to the mutation.payload.data: An object containing the data that was returned by themutation.payload.errors: An array of any errors that occurred during themutation's execution. If the mutation was successful, this array will beempty.
Example
Here's how you can access the mutation variables and the returned data:
Node.js
import{onMutationExecuted}from"firebase-functions/dataconnect";import{logger}from"firebase-functions";exportconstprocessNewUserData=onMutationExecuted({"service":"myAppService","connector":"users","operation":"CreateUser",},(event)=>{// The variables passed to the mutationconstmutationVariables=event.data.payload.variables;// The data returned by the mutationconstreturnedData=event.data.payload.data;logger.info("Processing mutation with variables:",mutationVariables);logger.info("Mutation returned:",returnedData);// ... your custom logic here});Python
fromfirebase_functionsimportdataconnect_fn,logger@dataconnect_fn.on_mutation_executed(service="myAppService",connector="users",operation="CreateUser"):defprocess_new_user_data(event:dataconnect_fn.Event):# The variables passed to the mutationmutation_vars=event.data.payload.variables# The data returned by the mutationreturned_data=event.data.payload.datalogger.info("Processing mutation with variables:",mutationVariables)logger.info("Mutation returned",returnedData)# ... your custom logic hereNote that unlike some other database triggers, such asCloud Firestore orRealtime Database, theData Connect event does not provide a "before"snapshot of the data. BecauseData Connect proxies requests to theunderlying database, the "before" snapshot of the data cannot be obtainedtransactionally. Instead, you have access to the arguments sent to the mutationand the data that was returned by it.
One consequence of this is that you cannot use the strategy of comparing"before" and "after" snapshots to avoid infinite loops, in which an eventtrigger triggers the same event. If you must perform a mutation from a functiontriggered by a mutation event, make use of event filters and take care to ensurethat no mutation can ever trigger itself, even indirectly.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-11-25 UTC.