Home > Back-end >  Best way to organize firebase writes on update trigger
Best way to organize firebase writes on update trigger

Time:05-02

There may be more than one correct answer to this question, but here's my issue: I have a user document in firebase with many fields that can be updated and which interact in different ways. If one field is updated, it may require a change to another field on the backend. Is it better to have a whole bunch of if statements each with their own write action if the condition is met or, or do single write at the end of the function for all the fields that might change. If a field does not change, I would have to write its original value back to itself. That seems clunky, but so does the other option. Am I missing a third option? What is the best practice here?

Here's an example of what I'm talking about. Updating fields one at a time is what I have now, which looks like this:

export const userUpdate = functions.firestore
    .document("users/{userID}")
    .onUpdate(async (change) => {
      const beforeData = change.before.data();
      const afterData = change.after.data();

// user levels up and gets more HP
    if(beforeData.userLevel != afterData.userLevel){
      const newMaxHP = 15   5 * afterData.userLevel;
      change.after.ref.update({
        maxHp: newMaxHP
      })
    }

//update user rating      
      if (beforeData.numberOfRatings != afterData.numberOfRatings) {
        const newRating = placerRating(beforeData.userRating, beforeData.numberOfRatings, afterData.latestRating);
        change.after.ref.update({
          userRating: newRating
        })
      } 

//replenish user funds from zero      
      if (afterData.money == 0){
        change.after.ref.update({
          money: 20
        })
      }

If I did it all in a single write, the if statements would assign a value to a variable, but not update the firestore document. Each if statement would include an else statement assigning the variable to the field's original value. There would be a single write at the end like this:

     change.after.ref.update({
        maxHp: newMaxHP,
        userRating: newRating,
        money: 20
      })

I hope that helps.

CodePudding user response:

Every time you call update(), you are being charged for 1 write operation. It'll be best to accumulate all updated fields in an object and then update the document only once as it'll be more efficient too. Try refactoring the code as shown below:

export const userUpdate = functions.firestore
  .document("users/{userID}")
  .onUpdate(async (change) => {
    const beforeData = change.before.data();
    const afterData = change.after.data();

    const updatedData = {};

    // user levels up and gets more HP
    if (beforeData.userLevel != afterData.userLevel) {
      const newMaxHP = 15   5 * afterData.userLevel;
      updatedData.maxHp = newMaxHP;
    }

    //update user rating      
    if (beforeData.numberOfRatings != afterData.numberOfRatings) {
      const newRating = placerRating(beforeData.userRating, beforeData.numberOfRatings, afterData.latestRating);
      updatedData.userRating = newRating;
    }

    //replenish user funds from zero      
    if (afterData.money == 0) {
      updatedData.money = 20;
    }

    await change.after.ref.update(updatedData);
    console.log("Data updated");
    return null;
  })
  • Related