Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

firebase best practice to prevent double spending in firestore. (Lock a document or field while modifying it)

Let’s say I have a collection of Employees and a collection of Departments. And I have cloud functions set to update the employees count in a department whenever an employee is created or deleted.

import * as functions from "firebase-functions";
import admin = require("firebase-admin");


export const handleEmployeeDeletion = functions.firestore
  .document('Employee/{employeeId}')
  .onDelete((snapshot, context) => {
    const departmentRef = admin.firestore()
      .collection("Department").doc(snapshot.data.departmentId);
    return departmentRef.update({
      employeesCount: admin.firestore.FieldValue.increment(-1)
    })
  })

What happens if two employee documents are deleted exactly at the same time? Am I safe from double-spending as long as I’m using the firestore.FieldValue.increment rather than reading the current value to the RAM of the Cloud Function and then writing the updated (And possibly outdated) value from there?

How about if the change that needs to be done to the field involves more calculations than simply incrementing? How can I make the changes while making sure there’s no chance multiple sessions will be modifying the same field at the same time after reading the same old value of the field?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

What happens if two employee documents are deleted exactly at the same time?

The function is invoked twice, meaning that the value is decremented twice. This also means that you’ll have to pay for two writes.

Am I safe from double-spending as long as I’m using the firestore.FieldValue.increment rather than reading the current value to the RAM of the Cloud Function and then writing the updated (And possibly outdated) value from there?

If you’re using the incrementation, you save two reads. Because if you want to read them first and then increment, you have to pay two reads and two writes.

How about if the change that needs to be done to the field involves more calculations than simply incrementing? How can I make the changes while making sure there’s no chance multiple sessions will be modifying the same field at the same time after reading the same old value of the field?

In that case, you need to use a transaction, which assures you that you’ll always have consistent data, no matter how many concurrent increment operations are performed.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading