Firestore batched writes and transactions
When to use them and why should they be used?

Just a guy who loves to write code and watch anime.
Search for a command to run...
When to use them and why should they be used?

Just a guy who loves to write code and watch anime.
No comments yet. Be the first to comment.
Qualities that make outstanding builders.

Bipedal vs quadrupedal: how many legs This is about the number of legs the creature walks on. Bipedal. Two legs. Humans, ostriches, T-rex, kangaroos, most fantasy humanoids. Quadrupedal. Four legs. Do

Intro You hear "lerp" and "smoothstep" everywhere in game dev. They sound like math jargon. They're not. Both are small tools that do the same job: smoothly move from one value to another. The problem

What is Kinematics Kinematics is the math field. It's the study of how things move without worrying about forces (which would be dynamics). FK and IK are the two branches: forward kinematics and inver

Intro Textures are usually the biggest cost in a 3D scene. Memory, bandwidth, and load time all get eaten by them. Resizing them is the obvious lever. There's more. This post is about the less obvious

At Bobsled, the start-up I work for, we use Firestore. There are places where we use batched writes and transactions. Before I joined Bobsled though, I didn't know about transactions, and only knew about batched writes.
In this article, I want to clear up when you should use each, as it was slightly confusing for me at the beginning when I heard of transactions.
Both batched writes and transactions are atomic operations, meaning, either all of their operations succeed, or none of them are applied.
Transactions should be used when you want to modify a document based on one of its current values, or the value of some other field.
All write operations execute at the end of a successful transaction, they never happen partially.
Notes from Transactions:
Below example taken from Transactions:
import { runTransaction } from "firebase/firestore";
try {
await runTransaction(db, async (transaction) => {
const sfDoc = await transaction.get(sfDocRef);
if (!sfDoc.exists()) {
throw "Document does not exist!";
}
const newPopulation = sfDoc.data().population + 1;
transaction.update(sfDocRef, { population: newPopulation });
});
console.log("Transaction successfully committed!");
} catch (e) {
console.log("Transaction failed: ", e);
}
If you don't need to read data, and based on that data write to Firestore, you can execute multiple write operations as a single batch.
Below example taken from Batched writes:
import { writeBatch, doc } from "firebase/firestore";
// Get a new write batch
const batch = writeBatch(db);
// Set the value of 'NYC'
const nycRef = doc(db, "cities", "NYC");
batch.set(nycRef, { name: "New York City" });
// Update the population of 'SF'
const sfRef = doc(db, "cities", "SF");
batch.update(sfRef, { population: 1000000 });
// Delete the city 'LA'
const laRef = doc(db, "cities", "LA");
batch.delete(laRef);
// Commit the batch
await batch.commit();
A batched write can consist of up to 500 operations. It also doesn't need to make sure that documents read remain un-modified.
To recap:
If you need to do multiple writes at the same time, but don't need to write based on data you've read from Firestore, then go with batched writes.
If you need to read data from Firestore and based on that data make writes, then go with transactions.
Batched writes and transactions can come across as quite similar when hearing them for the first time, and sometimes it can be hard to know when to use each, I hope this cleared up the topic.