Cloud Firestore triggers Stay organized with collections Save and categorize content based on your preferences.
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:
- Waits for changes to a particular document.
- Triggers when an event occurs and performs its tasks.
- 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 Type | Trigger |
|---|---|
onDocumentCreated | Triggered when a document is written to for the first time. |
onDocumentUpdated | Triggered when a document already exists and has any value changed. |
onDocumentDeleted | Triggered when a document is deleted. |
onDocumentWritten | Triggered whenonDocumentCreated,onDocumentUpdated oronDocumentDeleted is triggered. |
onDocumentCreatedWithAuthContext | onDocumentCreated with additional authentication information |
onDocumentWrittenWithAuthContext | onDocumentWritten with additional authentication information |
onDocumentDeletedWithAuthContext | onDocumentDeleted with additional authentication information |
onDocumentUpdatedWithAuthContext | onDocumentUpdated with additional authentication information |
Python
| Event Type | Trigger |
|---|---|
on_document_created | Triggered when a document is written to for the first time. |
on_document_updated | Triggered when a document already exists and has any value changed. |
on_document_deleted | Triggered when a document is deleted. |
on_document_written | Triggered whenon_document_created,on_document_updated oron_document_deleted is triggered. |
on_document_created_with_auth_context | on_document_created with additional authentication information |
on_document_updated_with_auth_context | on_document_updated with additional authentication information |
on_document_deleted_with_auth_context | on_document_deleted with additional authentication information |
on_document_written_with_auth_context | on_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"}# TrueIn 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})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
onDocumentCreatedWithAuthContextonDocumentWrittenWithAuthContextonDocumentDeletedWithAuthContextonDocumentUpdatedWithAuthContext
Python
on_document_created_with_auth_contexton_document_updated_with_auth_contexton_document_deleted_with_auth_contexton_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_idData 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({# ...})Limitations
Note the following limitations forCloud Firestore triggers for Cloud Functions:
- Cloud Functions (1st gen) prerequisites an existing "(default)" database in Firestore native mode. It does notsupportCloud Firestore named databases or Datastore mode. Please useCloud Functions(2nd gen) to configure events in such cases.
- Cross project setup withCloud Functions andCloud Firestore trigger is a limitation. To setupCloud Firestore triggerCloud Functions must be in the same project.
- 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.
- Cloud Firestore in Datastore moderequiresCloud Functions (2nd gen).Cloud Functions (1st gen) does notsupport Datastore mode.
- A trigger is associated with a single database. You cannot create a trigger that matches multiple databases.
- Deleting a database does not automatically delete any triggers for that database. Thetrigger stops delivering events but continues to exist until youdelete the trigger.
- If a matched event exceeds themaximum request size, theevent might not be delivered toCloud Functions (1st gen).
- Events not delivered because of request size are logged inplatform logs and count towards the log usage for the project.
- You can find these logs in the Logs Explorer with the message "Event cannot deliver toCloud function due to size exceeding the limit for 1st gen..." of
errorseverity. You can find the function name under thefunctionNamefield. If thereceiveTimestampfield is still within an hour from now, you can inferthe actual event content by reading the document in question with a snapshot before and after the timestamp. - To avoid such cadence, you can:
- Migrate and upgrade toCloud Functions (2nd gen)
- Downsize the document
- Delete theCloud Functions in question
- You can turn off the logging itself usingexclusions but note that the offending events will still not be delivered.
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.