I am trying to use a Firestore data converter inside a transaction where I am adding a record to a collection (entries
) and updating a counter in another collection (users
). However, I cannot figure out how to use the converter inside a transaction, and have been unable to find any examples. While the Firebase docs are typically excellent, they seem to fall a bit short with regards to transactions.
// Add new entry and increment user entry counter
async addEntry(entry: Entry): Promise<void> {
const entryRef = db.collection("entries").doc(entry.id);
const userRef = db.collection("user").doc(entry.userId);
await db.runTransaction(async (transaction) => {
// NOTE: Cannot use converter with transaction???
await transaction.set(entryRef, entry).withConverter(entryConverter);
// QUESTION: Is this a proper use of "increment" (ie. inside a transaction)?
await transaction.update(userRef, { entries: FieldValue.increment(1) });
});
}
This is what it would look like without the transaction and using a converter (but I need the transaction).
await db.collection("entries")
.doc(entry.id)
.withConverter(entryConverter)
.set(entry);
await db.collection("users")
.doc(entry.userId)
.update({ entries: FieldValue.increment(1) });
How can I safely perform these two operations in a transaction while using a converter for the new data?
Indeed this is not documented, but you can set the converter outside the transaction and before specifying a document, since the converter is being applied to the collection, and it should work. So something like:
async addEntry(entry: Entry): Promise<void> {
const entryRef = db.collection("entries").withConverter(entryConverter).doc(entry.id);
const userRef = db.collection("user").doc(entry.userId);
await db.runTransaction(async (transaction) => {
await transaction.set(entryRef, entry);
await transaction.update(userRef, { entries: FieldValue.increment(1) });
});
}