Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I believe that this cloud function is not idempotent #51

Open
schevtso opened this issue Aug 8, 2019 · 3 comments
Open

I believe that this cloud function is not idempotent #51

schevtso opened this issue Aug 8, 2019 · 3 comments

Comments

@schevtso
Copy link

schevtso commented Aug 8, 2019

exports.aggregateRatings = functions.firestore
.document('restaurants/{restId}/ratings/{ratingId}')
.onWrite((change, context) => {
// Get value of the newly added rating
var ratingVal = change.after.data().rating;
// Get a reference to the restaurant
var restRef = db.collection('restaurants').doc(context.params.restId);
// Update aggregations in a transaction
return db.runTransaction(transaction => {
return transaction.get(restRef).then(restDoc => {
// Compute new number of ratings
var newNumRatings = restDoc.data().numRatings + 1;
// Compute new average rating
var oldRatingTotal = restDoc.data().avgRating * restDoc.data().numRatings;
var newAvgRating = (oldRatingTotal + ratingVal) / newNumRatings;
// Update restaurant info
return transaction.update(restRef, {
avgRating: newAvgRating,
numRatings: newNumRatings
});
});
});
});

If it's retried, I think it's possible to get a wrong value for newNumRatings.

@ghost
Copy link

ghost commented Jul 3, 2022

exports.aggregateRatings = functions.firestore
.document('restaurants/{restId}/ratings/{ratingId}')
.onWrite((change, context) => {
// Get value of the newly added rating
var ratingVal = change.after.data().rating;

   // Get a reference to the restaurant 
   var restRef = db.collection('restaurants').doc(context.params.restId); 

   // Update aggregations in a transaction 
   return db.runTransaction(transaction => { 
     return transaction.get(restRef).then(restDoc => { 
       // Compute new number of ratings 
       var newNumRatings = restDoc.data().numRatings + 1; 

       // Compute new average rating 
       var oldRatingTotal = restDoc.data().avgRating * restDoc.data().numRatings; 
       var newAvgRating = (oldRatingTotal + ratingVal) / newNumRatings; 

       // Update restaurant info 
       return transaction.update(restRef, { 
         avgRating: newAvgRating, 
         numRatings: newNumRatings 
       }); 
     }); 
   }); 
 }); 

2 similar comments
@ghost
Copy link

ghost commented Jul 3, 2022

exports.aggregateRatings = functions.firestore
.document('restaurants/{restId}/ratings/{ratingId}')
.onWrite((change, context) => {
// Get value of the newly added rating
var ratingVal = change.after.data().rating;

   // Get a reference to the restaurant 
   var restRef = db.collection('restaurants').doc(context.params.restId); 

   // Update aggregations in a transaction 
   return db.runTransaction(transaction => { 
     return transaction.get(restRef).then(restDoc => { 
       // Compute new number of ratings 
       var newNumRatings = restDoc.data().numRatings + 1; 

       // Compute new average rating 
       var oldRatingTotal = restDoc.data().avgRating * restDoc.data().numRatings; 
       var newAvgRating = (oldRatingTotal + ratingVal) / newNumRatings; 

       // Update restaurant info 
       return transaction.update(restRef, { 
         avgRating: newAvgRating, 
         numRatings: newNumRatings 
       }); 
     }); 
   }); 
 }); 

@ghost
Copy link

ghost commented Jul 3, 2022

exports.aggregateRatings = functions.firestore
.document('restaurants/{restId}/ratings/{ratingId}')
.onWrite((change, context) => {
// Get value of the newly added rating
var ratingVal = change.after.data().rating;

   // Get a reference to the restaurant 
   var restRef = db.collection('restaurants').doc(context.params.restId); 

   // Update aggregations in a transaction 
   return db.runTransaction(transaction => { 
     return transaction.get(restRef).then(restDoc => { 
       // Compute new number of ratings 
       var newNumRatings = restDoc.data().numRatings + 1; 

       // Compute new average rating 
       var oldRatingTotal = restDoc.data().avgRating * restDoc.data().numRatings; 
       var newAvgRating = (oldRatingTotal + ratingVal) / newNumRatings; 

       // Update restaurant info 
       return transaction.update(restRef, { 
         avgRating: newAvgRating, 
         numRatings: newNumRatings 
       }); 
     }); 
   }); 
 }); 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant