Search code examples
node.jsfirebasegoogle-cloud-platformgoogle-cloud-firestore

What happens if you call batch.commit() on Firebase and your quota is exceeded part way through the commit?


I have a Node.js application in which I make calls to a Firebase database. At certain points in my code, I commit database writes in batch like this:

batch.commit();

At a certain point, this line began to hang. I added some debugging code around it like this:

incrementLineNumbersAt(lineNum) {
...
  try {
    const p = batch.commit();
    console.log('got promise');
    return p;
  } catch(err) {
    console.log(`An error occurred: ${err});
  }
}

...and it printed out 'got promise', so I assume it returned the promise. Yet the promise chain where this function was called, which looks like this:

incrementLineNumbersAt(lineNumParsed).then(() => {
    console.log('Line numbers incremented');
    ...
}).catch(err) => {
    console.log(`err = ${err}`);
    res.status(500).send('Something went wrong when attempting to add content.');
})

...didn't print anything in the then block or the catch block, and the front end doesn't receive a response. This is what I mean by "hanging".

While trying to debug this code, I reached my Firebase quota and got the following error message (while trying to perform a different operation from the above):

{"code":8,"details":"Quota exceeded.","metadata":{"x-debug-tracking-id":["7944564146387179486;o=1"]}}

This tells me that what's probably happening is that while the batch.commit() is trying to update several records (thousands), it is hitting the quota and then rolling back. The rolling back explains why no records are updated in the database and why I can continue to do reads and writes to the database without immediately exceeding my quota.

Is this how batch.commit() works? Does it attempt to commit the batch in a transaction and roll back if it hits the quota? And if so, how can I tell? Does it throw an error? Why wasn't I able to catch the error?

Thanks!


Solution

  • When you get the following error:

    {"code":8,"details":"Quota exceeded.","metadata":{"x-debug-tracking-id":["7944564146387179486;o=1"]}}

    It means that you exceeded the daily quota. If you're using the Spark Plan (no-cost plan), you can perform up to 20,000 writes per day. If you reach this daily quota, the writes will start to fail, as you already noticed.

    Please keep in mind that Firebase quotas are reset daily at midnight (Pacific time). However, your timezone may also differ. For example, if you're located in Europe, it may be in the middle of the day. So, if you reach the daily limitation, you need to wait until the "next" day, or you can update the Blaze Plan, to get rid of such errors.

    This tells me that what's probably happening is that while the batch.commit() is trying to update several records (thousands), it is hitting the quota and then rolling back.

    Yes, that's probably what most likely happens.

    The rolling back explains why no records are updated in the database and why I can continue to do reads and writes to the database without immediately exceeding my quota.

    In this case, that's indeed what happens.

    Is this how batch.commit() works? Does it attempt to commit the batch in a transaction and roll back if it hits the quota?

    Yes, this is exactly how it works. When you execute multiple write operations as a single batch, each operation in the batch counts separately towards your Cloud Firestore usage. So for example, if the tenth operation in the batch causes the maximum daily limit to be reached, then the entire operation will fail. This means that either all operations succeed or all operations fail.

    Does it throw an error?

    Yes, when you reach the daily limitation, an error is thrown containing the exact message that exists inside your question.