Home > other >  Cannot modify a WriteBatch that has been committed in environment nodejs
Cannot modify a WriteBatch that has been committed in environment nodejs

Time:09-22

I am trying to batch commit but it does not work as expected here is my code

exports.test = functions.https.onRequest(async (req, res) => {
  const firestore = admin.firestore();
  const batch = firestore.batch();
  try {
    let snapUser = await admin.firestore().collection("users").get();
    const batch = firestore.batch();
    snapUser.docs.forEach(async (doc) => {
      let snapObject = await doc.ref.collection("objects").get();
      if (!objectSnapShot.empty) {
        objectSnapShot.docs.forEach((doc) => {
          batch.set(
            doc.ref,
            {
              category: doc.data().category,
            },
            {
              merge: true,
            }
          );
        });
       await batch.commit()

      }
    });


    res.status(200).send("success");
  } catch (error) {
    functions.logger.log("Error while deleting account", error);
  }
});

Am I doing something wrong ?

Any help would be appreciated

CodePudding user response:

The await batch.commit() runs in every iteration of the loop but you can only commit a batch once. You must commit it after the execution of the loop.

snapUser.docs.forEach(async (doc) => {
  // add operations to batch 
});

await batch.commit()

Also, it might be better to use for loop when using async-await instead of a forEach() loop. Checkout Using async/await with a forEach loop for more information.

CodePudding user response:

You can receive this errors in cases where transactions have been committed and or you are using the same batch object to perform several commits. You can go ahead and create a new batch object for every commit, if necessary. You may try to start small and break things down to really understand the concepts. It seems the WriteBatch is being closed before asynchronous operations try to write to it.
A batch process needs to have two parts, a main function and a callback from each batch. The issue is you are trying to redeclare the batch process once it's been committed for the first batch. Your main function is an async which will continue to run all methods asynchronously, ignoring any internal functions. You must make sure that all jobs being applied to the batch are added before attempting to commit, at the core this is a race condition.
You can handle these in multiple ways, such as wrapping it with a promise chain or creating a callback. Check the following documentation for Managing Data Transactions.

  • Related