Saikat Bepari
Saikat Bepari

Reputation: 121

Cloud Function to Update a Record (value = value + newValue) whenever a value chages in Firebase Databse

I am new to Cloud Functions.

I have a table 'drivers' with having few details.

DB Snapshot

Now I want to write a Firebase Cloud Function which will

  1. trigger whenever the value in 'drivers/{driverId}/history/{rideId}/rating' is set.
  2. Update totalRating (drivers/{driverId}/totalRating) value to oldTotalRatingValue + NewTotalRatingValue.

Any help or a reference would be appreciated.

Thanks in Advance.

=============My Approach======================

exports.increaseRating = functions.database.ref('/drivers/{driverId}/history/{historyId}/rating')
.onUpdate((snapshot, context) => {
    var newRating = snapshot.after.val();
    var oldRating = 0;
    var db = admin.database();
    var ref = db.ref(`/drivers/${context.params.driverId}/totalRating`);
    ref.once("value", function(snapshot) {
      oldRating = snapshot.val();
    });
    console.log(oldRating);
    var finalRating = oldRating + newRating;
    return admin.database().ref(`/drivers/${context.params.driverId}`).update({
        "totalRating": finalRating,
    })
})

but my var oldRating doesn't updates to database value.

Upvotes: 0

Views: 57

Answers (2)

Renaud Tarnec
Renaud Tarnec

Reputation: 83048

You need to use a Transaction if you want to update the totalRanking, in order to avoid that another instance of the Cloud Function writes to the totalRanking location before your new value is successfully written by the current Cloud Function.

The following should work (untested):

exports.increaseRating = functions.database.ref('/drivers/{driverId}/history/{historyId}/rating')
    .onUpdate((snapshot, context) => {

        const newRating = snapshot.after.val();

        const totalRatingRef = admin.database().ref(`/drivers/${context.params.driverId}/totalRating`);

        return totalRatingRef.transaction(currentTotalRating => {
            // If /drivers/{driverId}/history/{historyId}/rating has never been set, newRating will be `null`.
            return currentTotalRating + newRating;
        });

    });

Note that we are returning the Promise returned by the Transaction. More details on this key point in the doc.

Upvotes: 2

vitooh
vitooh

Reputation: 4262

You have to write Cloud Fucntion with Realtime Database trigger onWrite. Here is documentation for this. The method documentation says:

Event handler that fires every time a Firebase Realtime Database write of any kind (creation, update, or delete) occurs.

Function should start more or less like:

...
exports.<your function name> = 
    functions.database.ref('drivers/{driverId}/history/{rideId}/rating')
    .onWrite((snapshot, context) => {
...

When it comes to updating you cloud function is node application so you can use firebase admin sdk in it. Tutorial is here. Just get value and update.

I can see you will need driverId for reference. You can get it from trigger wildcard like this context.params.driverId (check wildcard is in trigger doc).

Upvotes: 0

Related Questions