Cloud Firestore triggers

WithCloud Functions, you can handle events inCloud Firestore with no need to update client code.You can make Cloud Firestore changes via thedocument snapshot interface or via theAdmin SDK.

In a typical lifecycle, a Cloud Firestore function does the following:

  1. Waits for changes to a particular document.
  2. Triggers when an event occurs and performs its tasks.
  3. Receives a data object that contains a snapshot of the data storedin the specified document. For write or update events, thedata object contains two snapshots that represent the data state beforeand after the triggering event.

Distance between the location of the Firestore instance and the locationof the function can create significant network latency. To optimize performance,consider specifying thefunction location whereapplicable.

Cloud Firestore function triggers

TheCloud Functions for Firebase SDK exports the following Cloud Firestoreevent triggers to let you create handlers tied to specific Cloud Firestoreevents:

Node.js

Event TypeTrigger
onDocumentCreatedTriggered when a document is written to for the first time.
onDocumentUpdatedTriggered when a document already exists and has any value changed.
onDocumentDeletedTriggered when a document is deleted.
onDocumentWrittenTriggered whenonDocumentCreated,onDocumentUpdated oronDocumentDeleted is triggered.
onDocumentCreatedWithAuthContextonDocumentCreated with additional authentication information
onDocumentWrittenWithAuthContextonDocumentWritten with additional authentication information
onDocumentDeletedWithAuthContextonDocumentDeleted with additional authentication information
onDocumentUpdatedWithAuthContextonDocumentUpdated with additional authentication information

Python

Event TypeTrigger
on_document_createdTriggered when a document is written to for the first time.
on_document_updatedTriggered when a document already exists and has any value changed.
on_document_deletedTriggered when a document is deleted.
on_document_writtenTriggered whenon_document_created,on_document_updated oron_document_deleted is triggered.
on_document_created_with_auth_contexton_document_created with additional authentication information
on_document_updated_with_auth_contexton_document_updated with additional authentication information
on_document_deleted_with_auth_contexton_document_deleted with additional authentication information
on_document_written_with_auth_contexton_document_written with additional authentication information

Cloud Firestore events trigger onlyon document changes. An update to a Cloud Firestore document where datais unchanged (a no-op write) does not generate an update or write event. It isnot possible to add events to specific fields.

If you don't have a project enabled forCloud Functions for Firebase yet, then readGet started withCloud Functions for Firebase (2nd gen)to configure and set up yourCloud Functions for Firebase project.

Writing Cloud Firestore-triggered functions

Define a function trigger

To define a Cloud Firestore trigger, specify a document path and an event type:

Node.js

const{onDocumentWritten,onDocumentCreated,onDocumentUpdated,onDocumentDeleted,Change,FirestoreEvent}=require('firebase-functions/v2/firestore');exports.myfunction=onDocumentWritten("my-collection/{docId}",(event)=>{/* ... */});

Python

fromfirebase_functions.firestore_fnimport(on_document_created,on_document_deleted,on_document_updated,on_document_written,Event,Change,DocumentSnapshot,)@on_document_created(document="users/{userId}")defmyfunction(event:Event[DocumentSnapshot])->None:

Document paths can reference either aspecific documentor awildcard pattern.

Specify a single document

If you want to trigger an event forany change to a specific document thenyou can use the following function.

Node.js

const{onDocumentWritten,Change,FirestoreEvent}=require('firebase-functions/v2/firestore');exports.myfunction=onDocumentWritten("users/marie",(event)=>{// Your code here});

Python

fromfirebase_functions.firestore_fnimport(on_document_written,Event,Change,DocumentSnapshot,)@on_document_written(document="users/marie")defmyfunction(event:Event[Change[DocumentSnapshot]])->None:

Specify a group of documents using wildcards

If you want to attach a trigger to a group of documents, such as any document ina certain collection, then use a{wildcard} in place of thedocument ID:

Node.js

const{onDocumentWritten,Change,FirestoreEvent}=require('firebase-functions/v2/firestore');exports.myfunction=onDocumentWritten("users/{userId}",(event)=>{// If we set `/users/marie` to {name: "Marie"} then// event.params.userId == "marie"// ... and ...// event.data.after.data() == {name: "Marie"}});

Python

fromfirebase_functions.firestore_fnimport(on_document_written,Event,Change,DocumentSnapshot,)@on_document_written(document="users/{userId}")defmyfunction(event:Event[Change[DocumentSnapshot]])->None:# If we set `/users/marie` to {name: "Marie"} thenevent.params["userId"]=="marie"# True# ... and ...event.data.after.to_dict()=={"name":"Marie"}# True

In this example, when any field on any document inusers is changed, it matchesa wildcard calleduserId.

If a document inusers has subcollections and a field in one of thosesubcollections' documents is changed, theuserId wildcard isnot triggered.

Wildcard matches are extracted from the document path and stored intoevent.params.You may define as many wildcards as you like to substitute explicit collectionor document IDs, for example:

Node.js

const{onDocumentWritten,Change,FirestoreEvent}=require('firebase-functions/v2/firestore');exports.myfunction=onDocumentWritten("users/{userId}/{messageCollectionId}/{messageId}",(event)=>{// If we set `/users/marie/incoming_messages/134` to {body: "Hello"} then// event.params.userId == "marie";// event.params.messageCollectionId == "incoming_messages";// event.params.messageId == "134";// ... and ...// event.data.after.data() == {body: "Hello"}});

Python

fromfirebase_functions.firestore_fnimport(on_document_written,Event,Change,DocumentSnapshot,)@on_document_written(document="users/{userId}/{messageCollectionId}/{messageId}")defmyfunction(event:Event[Change[DocumentSnapshot]])->None:# If we set `/users/marie/incoming_messages/134` to {body: "Hello"} thenevent.params["userId"]=="marie"# Trueevent.params["messageCollectionId"]=="incoming_messages"# Trueevent.params["messageId"]=="134"# True# ... and ...event.data.after.to_dict()=={"body":"Hello"}

Your trigger mustalways point to a document, even if you're using a wildcard.For example,users/{userId}/{messageCollectionId} is not valid because{messageCollectionId}is a collection. However,users/{userId}/{messageCollectionId}/{messageId}isvalid because{messageId} will always point to a document.

Event Triggers

Trigger a function when a new document is created

You can trigger a function to fire any time a new document is created in a collection.This example function triggers every time a new user profile is added:

Node.js

const{onDocumentCreated,Change,FirestoreEvent}=require('firebase-functions/v2/firestore');exports.createuser=onDocumentCreated("users/{userId}",(event)=>{// Get an object representing the document// e.g. {'name': 'Marie', 'age': 66}constsnapshot=event.data;if(!snapshot){console.log("No data associated with the event");return;}constdata=snapshot.data();// access a particular field as you would any JS propertyconstname=data.name;// perform more operations ...});

For additional authentication information, useonDocumentCreatedWithAuthContext.

Python

fromfirebase_functions.firestore_fnimport(on_document_created,Event,DocumentSnapshot,)@on_document_created(document="users/{userId}")defmyfunction(event:Event[DocumentSnapshot])->None:# Get a dictionary representing the document# e.g. {'name': 'Marie', 'age': 66}new_value=event.data.to_dict()# Access a particular field as you would any dictionaryname=new_value["name"]# Perform more operations ...

Trigger a function when a document is updated

You can also trigger a function to fire when a document is updated.This example function fires if a user changes their profile:

Node.js

const{onDocumentUpdated,Change,FirestoreEvent}=require('firebase-functions/v2/firestore');exports.updateuser=onDocumentUpdated("users/{userId}",(event)=>{// Get an object representing the document// e.g. {'name': 'Marie', 'age': 66}constnewValue=event.data.after.data();// access a particular field as you would any JS propertyconstname=newValue.name;// perform more operations ...});

For additional authentication information, useonDocumentUpdatedWithAuthContext.

Python

fromfirebase_functions.firestore_fnimport(on_document_updated,Event,Change,DocumentSnapshot,)@on_document_updated(document="users/{userId}")defmyfunction(event:Event[Change[DocumentSnapshot]])->None:# Get a dictionary representing the document# e.g. {'name': 'Marie', 'age': 66}new_value=event.data.after.to_dict()# Access a particular field as you would any dictionaryname=new_value["name"]# Perform more operations ...

Trigger a function when a document is deleted

You can also trigger a function when a document is deleted. This examplefunction fires when a user deletes their user profile:

Node.js

const{onDocumentDeleted,Change,FirestoreEvent}=require('firebase-functions/v2/firestore');exports.deleteuser=onDocumentDeleted("users/{userId}",(event)=>{// Get an object representing the document// e.g. {'name': 'Marie', 'age': 66}constsnap=event.data;constdata=snap.data();// perform more operations ...});

For additional authentication information, useonDocumentDeletedWithAuthContext.

Python

fromfirebase_functions.firestore_fnimport(on_document_deleted,Event,DocumentSnapshot,)@on_document_deleted(document="users/{userId}")defmyfunction(event:Event[DocumentSnapshot|None])->None:# Perform more operations ...

Trigger a function for all changes to a document

If you don't care about the type of event being fired, you can listen for allchanges in a Cloud Firestore document using the "document written" eventtrigger. This example function fires if a user is created, updated, or deleted:

Node.js

const{onDocumentWritten,Change,FirestoreEvent}=require('firebase-functions/v2/firestore');exports.modifyuser=onDocumentWritten("users/{userId}",(event)=>{// Get an object with the current document values.// If the document does not exist, it was deletedconstdocument=event.data.after.data();// Get an object with the previous document valuesconstpreviousValues=event.data.before.data();// perform more operations ...});

For additional authentication information, useonDocumentWrittenWithAuthContext.

Python

fromfirebase_functions.firestore_fnimport(on_document_written,Event,Change,DocumentSnapshot,)@on_document_written(document="users/{userId}")defmyfunction(event:Event[Change[DocumentSnapshot|None]])->None:# Get an object with the current document values.# If the document does not exist, it was deleted.document=(event.data.after.to_dict()ifevent.data.afterisnotNoneelseNone)# Get an object with the previous document values.# If the document does not exist, it was newly created.previous_values=(event.data.before.to_dict()ifevent.data.beforeisnotNoneelseNone)# Perform more operations ...

Reading and Writing Data

When a function is triggered, it provides a snapshot of the data related to theevent. You can use this snapshot to read from or write to the document thattriggered the event, or use the Firebase Admin SDK to access other partsof your database.

Event Data

Reading Data

When a function is triggered, you might want to get data from a document thatwas updated, or get the data prior to update. You can get the prior data by usingevent.data.before, which contains the document snapshot before the update.Similarly,event.data.after contains the document snapshot state after theupdate.

Node.js

exports.updateuser2=onDocumentUpdated("users/{userId}",(event)=>{// Get an object with the current document values.// If the document does not exist, it was deletedconstnewValues=event.data.after.data();// Get an object with the previous document valuesconstpreviousValues=event.data.before.data();});

Python

@on_document_updated(document="users/{userId}")defmyfunction(event:Event[Change[DocumentSnapshot]])->None:# Get an object with the current document values.new_value=event.data.after.to_dict()# Get an object with the previous document values.prev_value=event.data.before.to_dict()

You can access properties as you would in any other object. Alternatively, youcan use theget function to access specific fields:

Node.js

// Fetch data using standard accessorsconstage=event.data.after.data().age;constname=event.data.after.data()['name'];// Fetch data using built in accessorconstexperience=event.data.after.data.get('experience');

Python

# Get the value of a single document field.age=event.data.after.get("age")# Convert the document to a dictionary.age=event.data.after.to_dict()["age"]

Writing Data

Each function invocation is associated with a specific document in yourCloud Firestore database. You can access that document in the snapshot returned to your function.

The document reference includes methods likeupdate(),set(), andremove()so you can modify the document that triggered the function.

Node.js

const{onDocumentUpdated}=require('firebase-functions/v2/firestore');exports.countnamechanges=onDocumentUpdated('users/{userId}',(event)=>{// Retrieve the current and previous valueconstdata=event.data.after.data();constpreviousData=event.data.before.data();// We'll only update if the name has changed.// This is crucial to prevent infinite loops.if(data.name==previousData.name){returnnull;}// Retrieve the current count of name changesletcount=data.name_change_count;if(!count){count=0;}// Then return a promise of a set operation to update the countreturnevent.data.after.ref.set({name_change_count:count+1},{merge:true});});

Python

@on_document_updated(document="users/{userId}")defmyfunction(event:Event[Change[DocumentSnapshot]])->None:# Get the current and previous document values.new_value=event.data.afterprev_value=event.data.before# We'll only update if the name has changed.# This is crucial to prevent infinite loops.ifnew_value.get("name")==prev_value.get("name"):return# Retrieve the current count of name changescount=new_value.to_dict().get("name_change_count",0)# Update the countnew_value.reference.update({"name_change_count":count+1})
Warning: Any time you write to the same document that triggered a function, youare at risk of creating an infinite loop. Use caution and ensure that you safelyexit the function when no change is needed.

Access user authentication information

If you use one of the of the following event types, you can accessuser authentication information about the principal that triggered the event.This information is in addition to the information returned in the base event.

Node.js

  • onDocumentCreatedWithAuthContext
  • onDocumentWrittenWithAuthContext
  • onDocumentDeletedWithAuthContext
  • onDocumentUpdatedWithAuthContext

Python

  • on_document_created_with_auth_context
  • on_document_updated_with_auth_context
  • on_document_deleted_with_auth_context
  • on_document_written_with_auth_context

For information about the data available in the authentication context, seeAuth Context.The following example demonstrates how to retrieve authentication information:

Node.js

const{onDocumentWrittenWithAuthContext}=require('firebase-functions/v2/firestore');exports.syncUser=onDocumentWrittenWithAuthContext("users/{userId}",(event)=>{constsnapshot=event.data.after;if(!snapshot){console.log("No data associated with the event");return;}constdata=snapshot.data();// retrieve auth context from eventconst{authType,authId}=event;letverified=false;if(authType==="system"){// system-generated users are automatically verifiedverified=true;}elseif(authType==="unknown"||authType==="unauthenticated"){// admin users from a specific domain are verifiedif(authId.endsWith("@example.com")){verified=true;}}returndata.after.ref.set({created_by:authId,verified,},{merge:true});});

Python

@on_document_updated_with_auth_context(document="users/{userId}")defmyfunction(event:Event[Change[DocumentSnapshot]])->None:# Get the current and previous document values.new_value=event.data.afterprev_value=event.data.before# Get the auth context from the eventuser_auth_type=event.auth_typeuser_auth_id=event.auth_id

Data outside the trigger event

Cloud Functions execute in a trusted environment. They areauthorized as a service account on your project, and you can perform reads andwrites using theFirebase Admin SDK:

Node.js

const{initializeApp}=require('firebase-admin/app');const{getFirestore,Timestamp,FieldValue}=require('firebase-admin/firestore');initializeApp();constdb=getFirestore();exports.writetofirestore=onDocumentWritten("some/doc",(event)=>{db.doc('some/otherdoc').set({...});});exports.writetofirestore=onDocumentWritten('users/{userId}',(event)=>{db.doc('some/otherdoc').set({// Update otherdoc});});

Python

fromfirebase_adminimportfirestore,initialize_appimportgoogle.cloud.firestoreinitialize_app()@on_document_written(document="some/doc")defmyfunction(event:Event[Change[DocumentSnapshot|None]])->None:firestore_client:google.cloud.firestore.Client=firestore.client()firestore_client.document("another/doc").set({# ...})
Note: Reads and writes performed inCloud Functions are not controlled by yoursecurity rules, they can access any part of your database.

Limitations

Note the following limitations forCloud Firestore triggers for Cloud Functions:

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 2026-02-06 UTC.