firestore cloud functions onCreate/onDelete sometimes immediately triggered twice

firestore triggers
firestore cloud functions ondelete
firestore on delete trigger
firebase cloud functions write to database
cloud functions database triggers
firebase cloud functions wildcard
firestore context params
firestore actions

I have observed this behavior occasionally with both onCreate and onDelete triggers.

Both the executions happened for the same document created in firestore. There's only one document there so I don't understand how it could trigger the handler twice. the handler itself is very simple:

module.exports = functions.firestore.document('notes/{noteId}').onCreate((event) => {
  const db = admin.firestore();
  const params = event.params;
  const data =;
  // empty

this doesn't happen all the time. What am I missing?

See the Cloud Firestore Triggers Limitations and Guarantees:

Delivery of function invocations is not currently guaranteed. As the Cloud Firestore and Cloud Functions integration improves, we plan to guarantee "at least once" delivery. However, this may not always be the case during beta. This may also result in multiple invocations for a single event, so for the highest quality functions ensure that the functions are written to be idempotent.

There is a Firecast video with tips for implementing idempotence.

Also two Google Blog posts: the first, the second.

Cloud Firestore triggers, See the Cloud Firestore Triggers Limitations and Guarantees: Delivery of function invocations is not currently guaranteed. As the Cloud  I encounterd a problem with my firebase cloud function which is sometimes immediately triggered twice when used with firestore in combination. There seems to be someone with the same problem on

In my case I try to use eventId and transaction to prevent onCreate sometimes triggered twice

(you may need to save eventId in list and check if it exist if your function actually triggered often)

const functions = require('firebase-functions')
const admin = require('firebase-admin')
const db = admin.firestore()
exports = module.exports = functions.firestore.document('...').onCreate((snap, context) => {

  const prize = 1000
  const eventId = context.eventId
  if (!eventId) {
    return false

  // increment money
  const p1 = () => {
    const ref = db.doc('...')
    return db.runTransaction(t => {
        return t.get(ref).then(doc => {
          let money_total = 0
          if (doc.exists) {
            const eventIdLast =
            if (eventIdLast === eventId) {
              throw 'duplicated event'
            const m0 =
            if(m0 !== undefined) {
              money_total = m0 + prize
          } else {
            money_total = prize
          return t.set(ref, { 
            money_total: money_total,
            event_id_last: eventId
          }, {merge: true})

  // will execute p2 p3 p4 if p1 success
  const p2 = () => {

  const p3 = () => {

  const p4 = () => {

  return p1().then(() => {
    return Promise.all([p2(), p3(), p4()])
  }).catch((error) => {

onCreate fires two times · Issue #62 · firebase/firebase-functions , firestore cloud functions onCreate/onDelete sometimes immediately triggered twice - firebase. Cloud Functions supports these event handlers for Realtime Database: onWrite(), which triggers when data is created, updated, or deleted in the Realtime Database. onCreate(), which triggers when new data is created in the Realtime Database. onUpdate(), which triggers when data is updated in the Realtime Database.

Based on @saranpol's answer we use the below for now. We have yet to check if we actually get any duplicate event ids though.

const alreadyTriggered = eventId => {
  // Firestore doesn't support forward slash in ids and the eventId often has it
  const validEventId = eventId.replace('/', '')

  const firestore = firebase.firestore()
  return firestore.runTransaction(async transaction => {
    const ref = firestore.doc(`eventIds/${validEventId}`)
    const doc = await transaction.get(ref)
    if (doc.exists) {
      console.error(`Already triggered function for event: ${validEventId}`)
      return true
    } else {
      transaction.set(ref, {})
      return false

// Usage
if (await alreadyTriggered(context.eventId)) {

@star__hoshi/only-once 0.1.3 node npm open source project details , The Cloud Functions for Firebase SDK exports a functions.firestore object that allows onWrite, Triggered when onCreate , onUpdate or onDelete is triggered. That way we can wait for some work to be done--say, accessing some data from Cloud Firestore--and then complete an action based on the result, like writing that data to another location in Cloud Firestore. Let's set up Cloud Functions and then see how they can help compute our restaurants' average reviews. Setting up Cloud Functions

Comparing a char to a code-point?, onCreate fires two times #62 I'm also experiencing this occasionally with firestore(). Firebase Functions onCreate fires 2 or 3 times #315 Cloud Functions aims to fire at least once, which means it could fire more than  Cloud Functions for Firebaseplat_iosplat_androidplat_webplat_cppplat_unity. Cloud Functions for Firebase let you automatically run backend code in response to events triggered by Firebase features and HTTPS requests. Your code is stored in Google's cloud and runs in a managed environment.

get last date of year of a given date, UTF-16 String Comparison in Code Point Order, Sometimes, however, the sort firestore cloud functions onCreate/onDelete sometimes immediately triggered  Push secure logic into Cloud Functions. Sometimes code is best deployed to a backend you control, so you can update it at will, and it can’t be tampered with by malicious clients.

firebase, Note: Where Date is called as a constructor with more than one argument, the firestore cloud functions onCreate/onDelete sometimes immediately triggered  Firestore (Firebase DB) in those cases, Firebase has something called cloud functions. The actions this trigger can be attached to are ‘onCreate’ ‘onUpdate’ ‘onDelete’ or