Permadi
Permadi

Reputation: 55

Firestore transaction update multiple document

I want to update documents in one collection.

my_collection
     document_1
        field_1
        field_2
     document_2
        field_1
        field_2

My code:

exports.aggregateUsers = 
functions.firestore.document('users/{userId}').onWrite(function(change, 
context) {
const document = change.after.exists ? change.after.data() : null;
const oldDocument = change.before.data() || null;

return firestore.runTransaction(function(transaction) {
    var oldInstanceRef;
    var instanceRef;

    var oldInstanceDoc;
    var instanceDoc;
    if (document != null) {
        instanceRef = firestore.collection("counters").doc("instance_counter").collection("instances").doc(document.instance);
        instanceDoc = transaction.get(instanceRef);

        var newNumberOfUsers = (instanceDoc.data().number_of_users || 0) + 1;
        transaction.set(instanceRef, { number_of_users: newNumberOfUsers });
    } 
    if (oldDocument != null) {
        oldInstanceRef = firestore.collection("counters").doc("instance_counter").collection("instances").doc(oldDocument.instance);
        oldInstanceDoc = transaction.get(oldInstanceRef);

        var newPrevNumberOfUsers = (oldInstanceDoc.data().number_of_users || 0) + 1;
        transaction.set(instanceRef, { number_of_users: newPrevNumberOfUsers });
    }


}).catch(function(error) {
    console.log("invalid-argument", error.code, error.message);
});
});

Errors:

instanceDoc.data is not a function

I am using transcation in cloud function to aggregate number of users, not using distributed counter, because of low traffic app. My question is how to update field's value in each document? Thank you

Upvotes: 1

Views: 887

Answers (1)

narcello
narcello

Reputation: 499

I guess you forgot the async/await.

Try this:

  1. async before transaction parameter
  2. await before transaction.get(<some_ref_here>)

return firestore.runTransaction(async transaction => {
    var oldInstanceRef;
    var instanceRef;

    var oldInstanceDoc;
    var instanceDoc;
    if (document != null) {
        instanceRef = firestore.collection("counters").doc("instance_counter").collection("instances").doc(document.instance);
        instanceDoc = await transaction.get(instanceRef);

        var newNumberOfUsers = (instanceDoc.data().number_of_users || 0) + 1;
        transaction.set(instanceRef, { number_of_users: newNumberOfUsers });
    } 
    if (oldDocument != null) {
        oldInstanceRef = firestore.collection("counters").doc("instance_counter").collection("instances").doc(oldDocument.instance);
        oldInstanceDoc = await transaction.get(oldInstanceRef);

        var newPrevNumberOfUsers = (oldInstanceDoc.data().number_of_users || 0) + 1;
        transaction.set(instanceRef, { number_of_users: newPrevNumberOfUsers });
    }


}).catch(function(error) {
    console.log("invalid-argument", error.code, error.message);
});

Upvotes: 3

Related Questions