Firestore read/update array of documents in one transaction

I created inventory management using Firestore. User can update single inventory items (products) and create purchases and invoices. When user creates purchase (or invoice) application updates multiple products quantities,creates event for each product change, creates new purchase document (where i store purchase number and array of products and more...) and increments "purchase number".

The code:

const db_user = db.collection("users").doc(userUID);
let products = db_user.collection("products");
let productEvents = db_user.collection("productEvents");

jQuery.each(productsArrayToUpdate, function (index, value) {
    let product = products.doc(productsArrayToUpdate[index][0]);
    let outQTY = productsArrayToUpdate[index][1];
    //...
    db.runTransaction(function (transaction) {
        return transaction.get(product).then(function (doc) {
            if (!doc.exists) {
                Swal.fire("Document does not exist!");
            }
            //...
            let newProductQTY = (doc.data().productQTY) ? doc.data().productQTY - outQTY + inQTY : 0 - outQTY + inQTY;
            //1. UPDATE PRODUCT DOC WITH NEW QUANTITY
            transaction.update(product, {
                productQTY: newProductQTY,
                //...
            });
            //2. CREATE NEW DOC IN ANOTHER COLLECTION WITH THIS PRODUCT EVENT
            transaction.set(productEvents.doc(), {
                productSKU: doc.data().productSKU,
                //....
            });
        });
    }).then(function () {
        //...  
    }).catch(function (error) {
        //...
    });
});

//3. CREATE PURCHASE DOCUMENT FOR ALL
db_user.get().then(function (doc) {
    if (doc.exists) {
        let purchaseDoc = db_user.collection("purchases").doc();
        purchaseDoc.set({
            purchaseNumber: purchaseNumber,
            purchasePositions: dataTablePurchaseRows,
            //...
        });
        db_user.update({
            //INCREMENT PURCHASE DOCUMENT NUMBER
            purchaseNumber: firebase.firestore.FieldValue.increment(1)
        }).then(function () {
            //...
        }).catch(function (error) {
            //..
        });
    } else {
        //...
    }
}).catch(function (error) {
    //...
});

It works OK but sometimes it fails and I have mess in my inventory:( So my question is how to put array of docs to read/update and set new docs(for each event) inside of one transaction and then create my purchase document with increment number if transaction pass.

something like this:

return db.runTransaction(function (transaction) {

    productsArrayToUpdate.forEach(function (element,index) {

        let product = products.doc(element[0]);
        let outQTY = element[1];
        ...
        return transaction.get(product).then(function (doc) {
            transaction.update(product, {
                productQTY: newProductQTY,
                [warehouseIN]: newSelectedWarehouseQTYIN,
                productInventoryStatus: inventoryStatus
            });
          transaction.set(productEvents.doc(), {
                productSKU: doc.data().productSKU,
          //...
    }
}


Read more here: https://stackoverflow.com/questions/67393763/firestore-read-update-array-of-documents-in-one-transaction

Content Attribution

This content was originally published by awariat at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: