简体   繁体   中英

Firebase Cloud function update all entries in database

i have bunch of comments in Firebase database and i want to do some updates to the comments via Cloud Function ( this is simplified example, i will be doing some logic which does require Cloud Function ).

What i need to do is go through all the comments in the database, adjust its rating node and then update the database with adjusted comments.

I spent a lot of time researching this, but i am completely new to Cloud Functions, so i have realy hard time figuring this out. I am assuming i want to store all the changes to all the comments (there can be thousands of them) in the array or object and then do the update at one time instead of for each comment separately ?

Btw this code is not working, i am assuming the array and return is completely wrong.

exports.increaseRating = functions.database.ref('/comments/')
    .onUpdate((snapshot) => {   

        var updates = [];

        snapshot.before.forEach((element) => {
            var comment = element.val();
            comment.rating += 1000;
            updates.push(comment);
        });

        return updates;
    })

Code i am using to update one entry. I need to do the same thing for all the comments at one time.

exports.increaseRating = functions.database.ref('/comments/{commentId}')
    .onUpdate((snapshot, context) => {

        const comment = snapshot.before.val();
        const newRating = comment.rating += 1000;       

        const now = new Date().getTime();
        if (comment.lastUpdate) {
            if (comment.lastUpdate > now - (30 * 1000)) {
                return null;
            }
        }

        return admin.database().ref(`/comments/${context.params.commentId}`).update({
            "rating": newRating,
            "lastUpdate": now
        })
    })

If you want to update all child nodes, you can do something like this:

var ref = firebase.database().ref("comments"); // or admin.database().ref("comments")
ref.once("value").then((snapshot) => {
  var updates = {};
  snapshot.forEach((commentSnapshot => {
    var comment = commentSnapshot.val();
    var newRating = comment.rating + 1000;
    updates[commentSnapshot.key+"/rating"] = newRating;
  });
  ref.update(updates);
})

This performs a single multi-location update for all comments. Note that the performance benefit over performing separate updates is quite small, since Firebase pipelines the multiple requests over a single connection .

Also note that you should not put this in a Cloud Functions trigger on /comments , since that will lead to an endless loop: every time the comments get written, your function triggers, which updates the comments, which triggers the function again.

If you need this in Cloud Functions, you'll want to use a HTTP-triggered function, which is triggered by HTTP calls instead of database writes.

exports.updateCommentRatings = functions.https.onRequest((req, res) => {
  var ref = admin.database().ref("comments")
  ref.once("value").then((snapshot) => {
    var updates = {};
    snapshot.forEach((commentSnapshot => {
      var comment = commentSnapshot.val();
      var newRating = comment.rating + 1000;
      updates[commentSnapshot.key+"/rating"] = newRating;
    });
    ref.update(updates).then(() => {
      res.status(200).send("Comment ratings updated");
    });
  })
})

You can then periodically call this URL/function with a service like cron-job.org. For more on this see Cloud Functions for Firebase trigger on time? .

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