Trigger functions with Firestore documents

This guide shows examples of functions that are triggered when you make changesto a document inside of a specified collection.

Before you begin

Before you run the sample code in this guide, you'll need to do the following:

Examples

The following examples demonstrate how to write functions that respond to aFirestore trigger.

Example 1: Hello Firestore function

The following sample prints the fields of a triggering Firestore event:

Node.js

/** * Cloud Event Function triggered by a change to a Firestore document. */constfunctions=require('@google-cloud/functions-framework');constprotobuf=require('protobufjs');functions.cloudEvent('helloFirestore',asynccloudEvent=>{console.log(`Function triggered by event on:${cloudEvent.source}`);console.log(`Event type:${cloudEvent.type}`);console.log('Loading protos...');constroot=awaitprotobuf.load('data.proto');constDocumentEventData=root.lookupType('google.events.cloud.firestore.v1.DocumentEventData');console.log('Decoding data...');constfirestoreReceived=DocumentEventData.decode(cloudEvent.data);console.log('\nOld value:');console.log(JSON.stringify(firestoreReceived.oldValue,null,2));console.log('\nNew value:');console.log(JSON.stringify(firestoreReceived.value,null,2));});

Python

fromcloudevents.httpimportCloudEventimportfunctions_frameworkfromgoogle.events.cloudimportfirestore@functions_framework.cloud_eventdefhello_firestore(cloud_event:CloudEvent)->None:"""Triggers by a change to a Firestore document.    Args:        cloud_event: cloud event with information on the firestore event trigger    """firestore_payload=firestore.DocumentEventData()firestore_payload._pb.ParseFromString(cloud_event.data)print(f"Function triggered by change to:{cloud_event['source']}")print("\nOld value:")print(firestore_payload.old_value)print("\nNew value:")print(firestore_payload.value)

Go

// Package hellofirestore contains a Cloud Event Function triggered by a Cloud Firestore event.packagehellofirestoreimport("context""fmt""github.com/GoogleCloudPlatform/functions-framework-go/functions""github.com/cloudevents/sdk-go/v2/event""github.com/googleapis/google-cloudevents-go/cloud/firestoredata""google.golang.org/protobuf/proto")funcinit(){functions.CloudEvent("helloFirestore",HelloFirestore)}// HelloFirestore is triggered by a change to a Firestore document.funcHelloFirestore(ctxcontext.Context,eventevent.Event)error{vardatafirestoredata.DocumentEventData// If you omit `DiscardUnknown`, protojson.Unmarshal returns an error// when encountering a new or unknown field.options:=proto.UnmarshalOptions{DiscardUnknown:true,}err:=options.Unmarshal(event.Data(),&data)iferr!=nil{returnfmt.Errorf("proto.Unmarshal: %w",err)}fmt.Printf("Function triggered by change to: %v\n",event.Source())fmt.Printf("Old value: %+v\n",data.GetOldValue())fmt.Printf("New value: %+v\n",data.GetValue())returnnil}

Java

importcom.google.cloud.functions.CloudEventsFunction;importcom.google.events.cloud.firestore.v1.DocumentEventData;importcom.google.protobuf.InvalidProtocolBufferException;importio.cloudevents.CloudEvent;importjava.util.logging.Logger;publicclassFirebaseFirestoreimplementsCloudEventsFunction{privatestaticfinalLoggerlogger=Logger.getLogger(FirebaseFirestore.class.getName());@Overridepublicvoidaccept(CloudEventevent)throwsInvalidProtocolBufferException{DocumentEventDatafirestoreEventData=DocumentEventData.parseFrom(event.getData().toBytes());logger.info("Function triggered by event on: "+event.getSource());logger.info("Event type: "+event.getType());logger.info("Old value:");logger.info(firestoreEventData.getOldValue().toString());logger.info("New value:");logger.info(firestoreEventData.getValue().toString());}}

C#

usingCloudNative.CloudEvents;usingGoogle.Cloud.Functions.Framework;usingGoogle.Events.Protobuf.Cloud.Firestore.V1;usingMicrosoft.Extensions.Logging;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceFirebaseFirestore;publicclassFunction:ICloudEventFunction<DocumentEventData>{privatereadonlyILogger_logger;publicFunction(ILogger<Function>logger)=>_logger=logger;publicTaskHandleAsync(CloudEventcloudEvent,DocumentEventDatadata,CancellationTokencancellationToken){_logger.LogInformation("Function triggered by event on {subject}",cloudEvent.Subject);_logger.LogInformation("Event type: {type}",cloudEvent.Type);MaybeLogDocument("Old value",data.OldValue);MaybeLogDocument("New value",data.Value);// In this example, we don't need to perform any asynchronous operations, so the// method doesn't need to be declared async.returnTask.CompletedTask;}/// <summary>/// Logs the names and values of the fields in a document in a very simplistic way./// </summary>privatevoidMaybeLogDocument(stringmessage,Documentdocument){if(documentisnull){return;}// ConvertFields converts the Firestore representation into a .NET-friendly// representation.IReadOnlyDictionary<string,object>fields=document.ConvertFields();varfieldNamesAndTypes=fields.OrderBy(pair=>pair.Key).Select(pair=>$"{pair.Key}: {pair.Value}");_logger.LogInformation(message+": {fields}",string.Join(", ",fieldNamesAndTypes));}}

Deploy the Hello Firestore function

If you haven't already done so, set up yourFirestore database.

Click the tab for instructions using the tool of your choice.

Console

When you use the Google Cloud console to create a function, you can also add a triggerto your function. Follow these steps to create a trigger for your function:

  1. In the Google Cloud console, go to Cloud Run:

    Go to Cloud Run

  2. ClickWrite a function, and enter the function details. For moreinformation about configuring functions during deployment, seeDeploy functions.

  3. In theTrigger section, clickAdd trigger.

  4. SelectFirestore trigger.

  5. In theEventarc trigger pane, modify thetrigger details as follows:

    1. Enter a name for the trigger in theTrigger name field, or usethe default name.

    2. Select aTrigger type from the list:

      • Google Sources to specify triggers forPub/Sub, Cloud Storage, Firestore,and other Google event providers.

      • Third-party to integrate with non-Google providersthat offer an Eventarc source. For more information,seeThird-party events in Eventarc.

    3. SelectFirestore from theEvent provider list, to select a productthat provides the type of event for triggering your function. Forthe list of event providers, seeEvent providers and destinations.

    4. Selecttype=google.cloud.firestore.document.v1.written from theEvent type list. Yourtrigger configuration varies depending on the supported event type.For more information, seeEvent types.

    5. In the Filters section, select a database, operation and attribute values, or use the default selections.

    6. If theRegion field is enabled, select alocationfor the Eventarctrigger. In general, the location of an Eventarctrigger should match the location of the Google Cloud resource thatyou want to monitor for events. In most scenarios, you should alsodeploy your function in the same region. SeeUnderstand Eventarc locationsfor more details about Eventarc trigger locations.

    7. In theService account field, select a service account.Eventarc triggers are linked to service accounts touse as an identity when invoking your function. YourEventarc trigger's service account must have the permissionto invoke your function. By default, Cloud Runuses theCompute Engine default service account.

    8. Optionally, specify theService URL path to send the incomingrequest to. This is the relative path on the destination service towhich the events for the trigger should be sent. For example:/,/route,route, androute/subroute.

  6. Once you've completed the required fields, clickSave trigger.

gcloud

When you create a function using the gcloud CLI, you must firstdeploy your function, and then create atrigger. Follow these steps to create a trigger for your function:

  1. Run the following command in the directory that contains the sample codeto deploy your function:

    gcloud run deployFUNCTION \        --source . \        --functionFUNCTION_ENTRYPOINT \        --base-imageBASE_IMAGE_ID \        --regionREGION

    Replace:

    • FUNCTION with the name of the function you aredeploying. You can omit this parameter entirely,but you will be prompted for the name if you omit it.

    • FUNCTION_ENTRYPOINT with the entry point to your function inyour source code. This is the code Cloud Run executes when yourfunction runs. The value of this flag must be a function name orfully-qualified class name that exists in your source code.

    • BASE_IMAGE_ID with the base image environment for yourfunction. For more details about base images and the packages includedin each image, seeRuntimes base images.

    • REGION with the Google Cloudregion where you want to deployyour function. For example,europe-west1.

  2. Run the following command to create a trigger that filters events:

    gcloud eventarc triggers createTRIGGER_NAME  \    --location=EVENTARC_TRIGGER_LOCATION \    --destination-run-service=FUNCTION  \    --destination-run-region=REGION \    --event-filters=type=google.cloud.firestore.document.v1.written \    --event-filters=database='(default)' \    --event-data-content-type=application/protobuf \    --event-filters-path-pattern=document='users/{username}' \    --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com

    Replace:

    • TRIGGER_NAME with the name for your trigger.

    • EVENTARC_TRIGGER_LOCATION with the location forthe Eventarc trigger. In general, the location of anEventarc trigger should match the location of the Google Cloud resource that you want to monitor for events. In most scenarios, you should also deploy your function in the same region. For more information, seeEventarc locations.

    • FUNCTION with the name of the function you aredeploying.

    • REGION with the Cloud Runregionof the function.

    • PROJECT_NUMBER with your Google Cloud project number. Eventarc triggers are linked to service accounts to useas an identity when invoking your function. Your Eventarc trigger's service account must have the permission to invoke your function. Bydefault, Cloud Run uses the Default compute service account.

    Eachevent-filters flag specifies a type of event, with the functiontriggering only when an event meets all of the criteria specified in itsevent-filters flags. Each trigger must have anevent-filters flagspecifying a supportedevent type,such as a new document written to Firestore or a file uploadedto Cloud Storage. You can't change the event filter type after creation.To change the event filter type, you must create a new trigger anddelete the old one. Optionally, you can repeat the--event-filtersflag with a supported filter in the formATTRIBUTE=VALUE to add morefilters.

Terraform

To create an Eventarc trigger for a Cloud Run function,seeCreate a trigger using Terraform.

Use the other fields as is:

  • --event-filters=type=google.cloud.firestore.document.v1.writtenspecifies that the function is triggered when a document is created,updated or deleted, per thegoogle.cloud.firestore.document.v1.writtenevent type.
  • --event-filters=database='(default)' specifies the Firebasedatabase. For the default database name, use(default).
  • --event-filters-path-pattern=document='users/{username}' provides thepath pattern of the documents that should be monitored for relevant changes.This path pattern states that all documents in theusers collection shouldbe monitored. For more information, seeUnderstand path patterns.

Test the Hello Firestore function

To test the Hello Firestore function, set up a collection calledusers in yourFirestore database:

  1. In the Google Cloud console, go to the Firestore databases page:

    Go to Firestore

  2. ClickStart a collection.

  3. Specifyusers as the collection ID.

  4. To start adding the collection's first document, underAdd its first document accept the auto-generatedDocument ID.

  5. Add at least one field for the document, specifying a name and value.For example, inField name, enterusername, and inField value,enterrowan.

  6. When you're done, clickSave.

    This action creates a new document, thereby triggering your function.

  7. To confirm that your function was triggered, click the linked name of thefunction in the Google Cloud consoleCloud Run Overview page to opentheService details page.

  8. Select theLogs tab and look for this string:

Function triggered by change to: //firestore.googleapis.com/projects/your-project-id/databases/(default)'

Example 2: Convert to Uppercase function

The following example retrieves the value added by the user, converts the stringat that location to uppercase, and replaces the value with the uppercase string:

Node.js

Useprotobufjs to decode the eventdata. Include thegoogle.events.cloud.firestore.v1data.protoin your source.

constfunctions=require('@google-cloud/functions-framework');constFirestore=require('@google-cloud/firestore');constprotobuf=require('protobufjs');constfirestore=newFirestore({projectId:process.env.GOOGLE_CLOUD_PROJECT,});// Converts strings added to /messages/{pushId}/original to uppercasefunctions.cloudEvent('makeUpperCase',asynccloudEvent=>{console.log('Loading protos...');constroot=awaitprotobuf.load('data.proto');constDocumentEventData=root.lookupType('google.events.cloud.firestore.v1.DocumentEventData');console.log('Decoding data...');constfirestoreReceived=DocumentEventData.decode(cloudEvent.data);constresource=firestoreReceived.value.name;constaffectedDoc=firestore.doc(resource.split('/documents/')[1]);constcurValue=firestoreReceived.value.fields.original.stringValue;constnewValue=curValue.toUpperCase();if(curValue===newValue){// Value is already upper-case// Don't perform a(nother) write to avoid infinite loopsconsole.log('Value is already upper-case.');return;}console.log(`Replacing value:${curValue} -->${newValue}`);affectedDoc.set({original:newValue,});});

Python

fromcloudevents.httpimportCloudEventimportfunctions_frameworkfromgoogle.cloudimportfirestorefromgoogle.events.cloudimportfirestoreasfirestoredataclient=firestore.Client()# Converts strings added to /messages/{pushId}/original to uppercase@functions_framework.cloud_eventdefmake_upper_case(cloud_event:CloudEvent)->None:firestore_payload=firestoredata.DocumentEventData()firestore_payload._pb.ParseFromString(cloud_event.data)path_parts=firestore_payload.value.name.split("/")separator_idx=path_parts.index("documents")collection_path=path_parts[separator_idx+1]document_path="/".join(path_parts[(separator_idx+2):])print(f"Collection path:{collection_path}")print(f"Document path:{document_path}")affected_doc=client.collection(collection_path).document(document_path)cur_value=firestore_payload.value.fields["original"].string_valuenew_value=cur_value.upper()ifcur_value!=new_value:print(f"Replacing value:{cur_value} -->{new_value}")affected_doc.set({"original":new_value})else:# Value is already upper-case# Don't perform a second write (which can trigger an infinite loop)print("Value is already upper-case.")

Go

// Package upper contains a Firestore Cloud Function.packageupperimport("context""errors""fmt""log""os""strings""cloud.google.com/go/firestore"firebase"firebase.google.com/go/v4""github.com/GoogleCloudPlatform/functions-framework-go/functions""github.com/cloudevents/sdk-go/v2/event""github.com/googleapis/google-cloudevents-go/cloud/firestoredata""google.golang.org/protobuf/proto")// set the GOOGLE_CLOUD_PROJECT environment variable when deploying.varprojectID=os.Getenv("GOOGLE_CLOUD_PROJECT")// client is a Firestore client, reused between function invocations.varclient*firestore.Clientfuncinit(){// Use the application default credentials.conf:=&firebase.Config{ProjectID:projectID}// Use context.Background() because the app/client should persist across// invocations.ctx:=context.Background()app,err:=firebase.NewApp(ctx,conf)iferr!=nil{log.Fatalf("firebase.NewApp: %v",err)}client,err=app.Firestore(ctx)iferr!=nil{log.Fatalf("app.Firestore: %v",err)}// Register cloud event functionfunctions.CloudEvent("MakeUpperCase",MakeUpperCase)}// MakeUpperCase is triggered by a change to a Firestore document. It updates// the `original` value of the document to upper case.funcMakeUpperCase(ctxcontext.Context,eevent.Event)error{vardatafirestoredata.DocumentEventData// If you omit `DiscardUnknown`, protojson.Unmarshal returns an error// when encountering a new or unknown field.options:=proto.UnmarshalOptions{DiscardUnknown:true,}err:=options.Unmarshal(e.Data(),&data)iferr!=nil{returnfmt.Errorf("proto.Unmarshal: %w",err)}ifdata.GetValue()==nil{returnerrors.New("Invalid message: 'Value' not present")}fullPath:=strings.Split(data.GetValue().GetName(),"/documents/")[1]pathParts:=strings.Split(fullPath,"/")collection:=pathParts[0]doc:=strings.Join(pathParts[1:],"/")varoriginalStringValuestringifv,ok:=data.GetValue().GetFields()["original"];ok{originalStringValue=v.GetStringValue()}else{returnerrors.New("Document did not contain field \"original\"")}newValue:=strings.ToUpper(originalStringValue)iforiginalStringValue==newValue{log.Printf("%q is already upper case: skipping",originalStringValue)returnnil}log.Printf("Replacing value: %q -> %q",originalStringValue,newValue)newDocumentEntry:=map[string]string{"original":newValue}_,err=client.Collection(collection).Doc(doc).Set(ctx,newDocumentEntry)iferr!=nil{returnfmt.Errorf("Set: %w",err)}returnnil}

Java

importcom.google.cloud.firestore.Firestore;importcom.google.cloud.firestore.FirestoreOptions;importcom.google.cloud.firestore.SetOptions;importcom.google.cloud.functions.CloudEventsFunction;importcom.google.events.cloud.firestore.v1.DocumentEventData;importcom.google.events.cloud.firestore.v1.Value;importcom.google.protobuf.InvalidProtocolBufferException;importio.cloudevents.CloudEvent;importjava.util.Map;importjava.util.concurrent.ExecutionException;importjava.util.logging.Logger;publicclassFirebaseFirestoreReactiveimplementsCloudEventsFunction{privatestaticfinalLoggerlogger=Logger.getLogger(FirebaseFirestoreReactive.class.getName());privatefinalFirestorefirestore;privatestaticfinalStringFIELD_KEY="original";privatestaticfinalStringAPPLICATION_PROTOBUF="application/protobuf";publicFirebaseFirestoreReactive(){this(FirestoreOptions.getDefaultInstance().getService());}publicFirebaseFirestoreReactive(Firestorefirestore){this.firestore=firestore;}@Overridepublicvoidaccept(CloudEventevent)throwsInvalidProtocolBufferException,InterruptedException,ExecutionException{if(event.getData()==null){logger.warning("No data found in event!");return;}if(!event.getDataContentType().equals(APPLICATION_PROTOBUF)){logger.warning(String.format("Found unexpected content type %s, expected %s",event.getDataContentType(),APPLICATION_PROTOBUF));return;}DocumentEventDatafirestoreEventData=DocumentEventData.parseFrom(event.getData().toBytes());// Get the fields from the post-operation document snapshot// https://firebase.google.com/docs/firestore/reference/rest/v1/projects.databases.documents#DocumentMap<String,Value>fields=firestoreEventData.getValue().getFieldsMap();if(!fields.containsKey(FIELD_KEY)){logger.warning("Document does not contain original field");return;}StringcurrValue=fields.get(FIELD_KEY).getStringValue();StringnewValue=currValue.toUpperCase();if(currValue.equals(newValue)){logger.info("Value is already upper-case");return;}// Retrieve the document name from the resource path:// projects/{project_id}/databases/{database_id}/documents/{document_path}StringaffectedDoc=firestoreEventData.getValue().getName().split("/documents/")[1].replace("\"","");logger.info(String.format("Replacing values: %s --> %s",currValue,newValue));// Wait for the async call to completethis.firestore.document(affectedDoc).set(Map.of(FIELD_KEY,newValue),SetOptions.merge()).get();}}

C#

usingCloudNative.CloudEvents;usingGoogle.Cloud.Firestore;usingGoogle.Cloud.Functions.Framework;usingGoogle.Cloud.Functions.Hosting;usingGoogle.Events.Protobuf.Cloud.Firestore.V1;usingMicrosoft.AspNetCore.Hosting;usingMicrosoft.Extensions.DependencyInjection;usingMicrosoft.Extensions.Logging;usingSystem.Collections.Generic;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceFirestoreReactive;publicclassStartup:FunctionsStartup{publicoverridevoidConfigureServices(WebHostBuilderContextcontext,IServiceCollectionservices)=>services.AddSingleton(FirestoreDb.Create());}// Register the startup class to provide the Firestore dependency.[FunctionsStartup(typeof(Startup))]publicclassFunction:ICloudEventFunction<DocumentEventData>{privatereadonlyILogger_logger;privatereadonlyFirestoreDb_firestoreDb;publicFunction(ILogger<Function>logger,FirestoreDbfirestoreDb)=>(_logger,_firestoreDb)=(logger,firestoreDb);publicasyncTaskHandleAsync(CloudEventcloudEvent,DocumentEventDatadata,CancellationTokencancellationToken){// Get the recently-written value. This expression will result in a null value// if any of the following is true:// - The event doesn't contain a "new" document// - The value doesn't contain a field called "original"// - The "original" field isn't a stringstringcurrentValue=data.Value?.ConvertFields().GetValueOrDefault("original")asstring;if(currentValueisnull){_logger.LogWarning($"Event did not contain a suitable document");return;}stringnewValue=currentValue.ToUpperInvariant();if(newValue==currentValue){_logger.LogInformation("Value is already upper-cased; no replacement necessary");return;}// The CloudEvent subject is "documents/x/y/...".// The Firestore SDK FirestoreDb.Document method expects a reference relative to// "documents" (so just the "x/y/..." part). This may be simplified over time.if(cloudEvent.Subjectisnull||!cloudEvent.Subject.StartsWith("documents/")){_logger.LogWarning("CloudEvent subject is not a document reference.");return;}stringdocumentPath=cloudEvent.Subject.Substring("documents/".Length);_logger.LogInformation("Replacing '{current}' with '{new}' in '{path}'",currentValue,newValue,documentPath);await_firestoreDb.Document(documentPath).UpdateAsync("original",newValue,cancellationToken:cancellationToken);}}
Note: Updating the function-triggering Firestore document might createsubsequentupdated events, which might cascade into an infinite loop within yourfunction. To solve this problem, use trigger types that ignore updates (such ascreated), or configure your function to only write to Firestore if theunderlying value has changed.

Deploy the Convert to Uppercase function

If you haven't already done so, set up yourFirestore database.

Click the tab for instructions using the tool of your choice.

Console

When you use the Google Cloud console to create a function, you can also add a triggerto your function. Follow these steps to create a trigger for your function:

  1. In the Google Cloud console, go to Cloud Run:

    Go to Cloud Run

  2. ClickWrite a function, and enter the function details. For moreinformation about configuring functions during deployment, seeDeploy functions.

  3. In theTrigger section, clickAdd trigger.

  4. SelectFirestore trigger.

  5. In theEventarc trigger pane, modify thetrigger details as follows:

    1. Enter a name for the trigger in theTrigger name field, or usethe default name.

    2. Select aTrigger type from the list:

      • Google Sources to specify triggers forPub/Sub, Cloud Storage, Firestore,and other Google event providers.

      • Third-party to integrate with non-Google providersthat offer an Eventarc source. For more information,seeThird-party events in Eventarc.

    3. SelectFirestore from theEvent provider list, to select a productthat provides the type of event for triggering your function. Forthe list of event providers, seeEvent providers and destinations.

    4. Selecttype=google.cloud.firestore.document.v1.written from theEvent type list. Yourtrigger configuration varies depending on the supported event type.For more information, seeEvent types.

    5. In the Filters section, select a database, operation and attribute values, or use the default selections.

    6. If theRegion field is enabled, select alocationfor the Eventarctrigger. In general, the location of an Eventarctrigger should match the location of the Google Cloud resource thatyou want to monitor for events. In most scenarios, you should alsodeploy your function in the same region. SeeUnderstand Eventarc locationsfor more details about Eventarc trigger locations.

    7. In theService account field, select a service account.Eventarc triggers are linked to service accounts touse as an identity when invoking your function. YourEventarc trigger's service account must have the permissionto invoke your function. By default, Cloud Runuses theCompute Engine default service account.

    8. Optionally, specify theService URL path to send the incomingrequest to. This is the relative path on the destination service towhich the events for the trigger should be sent. For example:/,/route,route, androute/subroute.

  6. Once you've completed the required fields, clickSave trigger.

gcloud

When you create a function using the gcloud CLI, you must firstdeploy your function, and then create atrigger. Follow these steps to create a trigger for your function:

  1. Run the following command in the directory that contains the sample codeto deploy your function:

    gcloud run deployFUNCTION \        --source . \        --functionFUNCTION_ENTRYPOINT \        --base-imageBASE_IMAGE_ID \        --regionREGION

    Replace:

    • FUNCTION with the name of the function you aredeploying. You can omit this parameter entirely,but you will be prompted for the name if you omit it.

    • FUNCTION_ENTRYPOINT with the entry point to your function inyour source code. This is the code Cloud Run executes when yourfunction runs. The value of this flag must be a function name orfully-qualified class name that exists in your source code.

    • BASE_IMAGE_ID with the base image environment for yourfunction. For more details about base images and the packages includedin each image, seeRuntimes base images.

    • REGION with the Google Cloudregion where you want to deployyour function. For example,europe-west1.

  2. Run the following command to create a trigger that filters events:

    gcloud eventarc triggers createTRIGGER_NAME  \    --location=EVENTARC_TRIGGER_LOCATION \    --destination-run-service=FUNCTION  \    --destination-run-region=REGION \    --event-filters=type=google.cloud.firestore.document.v1.written \    --event-filters=database='(default)' \    --event-data-content-type=application/protobuf \    --event-filters-path-pattern=document='messages/{pushId}' \    --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com

    Replace:

    • TRIGGER_NAME with the name for your trigger.

    • EVENTARC_TRIGGER_LOCATION with the location forthe Eventarc trigger. In general, the location of anEventarc trigger should match the location of the Google Cloud resource that you want to monitor for events. In most scenarios, you should also deploy your function in the same region. For more information, seeEventarc locations.

    • FUNCTION with the name of the function you aredeploying.

    • REGION with the Cloud Runregionof the function.

    • PROJECT_NUMBER with your Google Cloud project number. Eventarc triggers are linked to service accounts to useas an identity when invoking your function. Your Eventarc trigger's service account must have the permission to invoke your function. Bydefault, Cloud Run uses the Default compute service account.

    Eachevent-filters flag specifies a type of event, with the functiontriggering only when an event meets all of the criteria specified in itsevent-filters flags. Each trigger must have anevent-filters flagspecifying a supportedevent type,such as a new document written to Firestore or a file uploadedto Cloud Storage. You can't change the event filter type after creation.To change the event filter type, you must create a new trigger anddelete the old one. Optionally, you can repeat the--event-filtersflag with a supported filter in the formATTRIBUTE=VALUE to add morefilters.

Terraform

To create an Eventarc trigger for a Cloud Run function,seeCreate a trigger using Terraform.

Use the other fields as is:

  • --event-filters=type=google.cloud.firestore.document.v1.writtenspecifies that the function is triggered when a document is created,updated or deleted, per thegoogle.cloud.firestore.document.v1.writtenevent type.
  • --event-filters=database='(default)' specifies theFirestore database. For the default database name, use(default).
  • --event-filters-path-pattern=document='messages/{pushId}' providesthe path pattern of the documents that should be monitored for relevantchanges. This path pattern states that all documents in themessagescollection should be monitored. For more information, seeUnderstand path patterns.

Test the Convert to Uppercase function

To test the Convert to Uppercase function you just deployed, set upa collection calledmessages in yourFirestore database:

  1. In the Google Cloud console, go to the Firestore databases page:

    Go to Firestore

  2. ClickStart a collection.

  3. Specifymessages as the collection ID.

  4. To start adding the collection's first document, underAdd its first document accept the auto-generatedDocument ID.

  5. To trigger your deployed function, add a document where theField name isoriginal and theField value isminka.

  6. When you save the document, you can see the lowercase word in the valuefield convert to uppercase.

    If you subsequently edit the field value to contain lowercase letters, thattriggers the function again, converting all lowercase letters touppercase.

Limitations for functions

  • Ordering is not guaranteed. Rapid changes can trigger function invocations inan unexpected order.
  • Events are delivered at least once, but a single event may result inmultiple function invocations. Avoid depending onexactly-once mechanics, and writeidempotent functions.
  • A trigger is associated with a single database. You cannot create a triggerthat matches multiple databases.
  • Deleting a database does not automatically delete any triggers for thatdatabase. The trigger stops delivering events but continues to exist until youdelete the trigger.

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-12-15 UTC.