简体   繁体   中英

Firebase transaction to update multiple fields in a document at once

I am trying to read a single field in a firestore document, increment the field by one and update the field along side two other fields in the document.

It seems firebase transaction update() function accept a JSON object with only one field and value because when I add other fields to the JSON, the update fails.

This works:

t.update(referralCodesDocRef, {field1: value1});

This does not work:

t.update(referralCodesDocRef, {
field1: value1,
field2: value2,
field3: value3
});

Also this does not work:

t.update(referralCodesDocRef, {field1: value1});
t.update(referralCodesDocRef, {field2: value2});
t.update(referralCodesDocRef, {field3: value3});

Here is the function that does the transaction

function runIncreaseCountTransaction(referralCodesDocRef){
    return db.runTransaction(t => {
      return t.get(referralCodesDocRef)
      .then(doc => {
        console.log(doc);
        let newReferralCount = doc.data().referral_count + 1;
        if(newReferralCount === max_referral_count){
          const current_time_millis = Date.now();
          const end_time_millis = current_time_millis+(180*1000); // ends after 3 mins
          t.update(referralCodesDocRef, {referral_count: newReferralCount});
          t.update(referralCodesDocRef, { timer_start_time: current_time_millis });
          t.update(referralCodesDocRef, { timer_end_time: end_time_millis });
        }
        else{
          t.update(referralCodesDocRef, { referral_count: newReferralCount });
        }
        return Promise.resolve(newReferralCount);
      })
      .then(result => {
        console.log('Success: Update successful: Referral count incremented!!', result);
        return true;
      }).catch(err => {
        console.log('Error: could not update referral count', err);
      });
    });
  }

So how can I achieve multiple fields update with firebase transactions?

There should be no problem at all to update a document with a JavaScript object composed of several properties, like

t.update(referralCodesDocRef, {
field1: value1,
field2: value2,
field3: value3
});

The problem most probably comes from the fact that you don't return the Transaction returned by the Transaction's update() method. The following should do the trick:

function runIncreaseCountTransaction(referralCodesDocRef){
    return db.runTransaction(t => {
      return t.get(referralCodesDocRef)
      .then(doc => {
        console.log(doc);
        let newReferralCount = doc.data().referral_count + 1;
        if (newReferralCount === max_referral_count) {
          const current_time_millis = Date.now();
          const end_time_millis = current_time_millis+(180*1000); // ends after 3 mins
          return t.update(referralCodesDocRef, 
          {
            referral_count: newReferralCount,
            timer_start_time: current_time_millis,
            timer_end_time: end_time_millis 
          });
        } else{
          return t.update(referralCodesDocRef, { referral_count: newReferralCount });
        }
      });
    })
    .then(result => {
      console.log('Success: Update successful: Referral count incremented!!', result);
      return null;
    })
    .catch(err => {
      console.log('Error: could not update referral count', err);
      return null;  //Note the return here.
    });
  }

Kotlin
You can update multiple fields in a Firestore document using the field, value, field, value... format:

db.collection("users").doc("docID").update({
    "field1", value1, // field, value
    "field1, "value2" // field, value
})

If you want to update a nested field, you have a couple options.

  1. Use the dot notation like you mentioned:

     db.collection("users").doc("docID").update({ "field1", value1, "field2.subfield2", value2, "field2.subfield3", value3 })
  2. Make your "value" a map:

     db.collection("users").doc("docID").update({ "field1", value1, "field2", mapOf( "field3" to value3, "field4" to value4 })

None of the answers are correct (at least didn't work for me).

Kotlin

Here is my implementation. Very easy:

val db = Firebase.firestore
                db.collection("Users")
                    .document("Ronaldo")
                    .update("famous", true,
                        "distance", 5)
                    .addOnSuccessListener {...
                    .addOnFailureListener {...

       

So basically add another comma after your first pair

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM