Firebase Cloud 功能更新数据库中的所有条目

人气:999 发布:2022-10-16 标签: javascript express firebase firebase-realtime-database google-cloud-functions

问题描述

我在 Firebase 数据库中有一堆评论,我想通过 Cloud Function 对评论进行一些更新(这是一个简化的示例,我将做一些需要 Cloud Function 的逻辑).

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 ).

我需要做的是浏览数据库中的所有评论,调整其评级节点,然后使用调整后的评论更新数据库.

我花了很多时间研究这个,但我对 Cloud Functions 完全陌生,所以我很难弄清楚这一点.我假设我想将所有评论的所有更改(可能有数千个)存储在数组或对象中,然后一次更新,而不是单独更新每个评论?

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);
})

这将对所有评论执行一次多位置更新.请注意,执行单独更新的性能优势非常小,因为 Firebase 通过单个连接对多个请求进行管道传输.

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.

还请注意,您应该不将其放在 /comments 上的 Cloud Functions 触发器中,因为这将导致无限循环:每次写入评论时,你的函数触发,更新评论,再次触发函数.

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.

如果您在 Cloud Functions 中需要此功能,则需要使用 HTTP 触发的函数,该函数由 HTTP 调用而不是数据库写入触发.

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");
    });
  })
})

然后,您可以使用 cron-job.org 等服务定期调用此 URL/函数.有关更多信息,请参阅 Cloud Functions for Firebase 准时触发?.

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?.

153