Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Firebase云函数-使用onWrite事件更新值_Javascript_Firebase_Google Cloud Functions - Fatal编程技术网

Javascript Firebase云函数-使用onWrite事件更新值

Javascript Firebase云函数-使用onWrite事件更新值,javascript,firebase,google-cloud-functions,Javascript,Firebase,Google Cloud Functions,有一个应用程序,其中一个用户可以评价另一个用户的图片,我想有一个用户已经收到的总票数计数。我发现使用Firebase实现此目标的最佳方法是控制“onWrite”事件,并在收到投票时手动更新每个用户的计数器 我发现以下代码存在的问题是,“votesCount”没有在第一个“onWrite”事件中准确更新,但在下一个“onWrite”事件中会使用前一个用户的速率进行更新。为什么会这样?对于投票应用程序来说,这是一个好方法吗 以下方法的目的是检查被投票的用户是否有“投票数”,如果为真,则将新值添加到旧

有一个应用程序,其中一个用户可以评价另一个用户的图片,我想有一个用户已经收到的总票数计数。我发现使用Firebase实现此目标的最佳方法是控制“onWrite”事件,并在收到投票时手动更新每个用户的计数器

我发现以下代码存在的问题是,“votesCount”没有在第一个“onWrite”事件中准确更新,但在下一个“onWrite”事件中会使用前一个用户的速率进行更新。为什么会这样?对于投票应用程序来说,这是一个好方法吗

以下方法的目的是检查被投票的用户是否有“投票数”,如果为真,则将新值添加到旧值中,反之,只需添加新值

exports.updateVotesCount = functions.database.ref('/votes/{id}').onWrite(event => {
   const data = event.data.val();
   var votesCount = admin.database().ref('/profiles/' + data.to).child('votes_count');
   votesCount.once('value').then(function(snapshot) {
      if (snapshot.val()) {
         votesCount.set(snapshot.val() + data.rate);
      } else {
         votesCount.set(data.rate);
      }
  });
});
这是我正在使用的数据结构的一个方面:

{
   profiles: [
      userId: {
         name: "...",
         image: "...",
         votes_count: "..."
      },
      ...
   ],
   votes: [
      voteId: {
         from: "userId",
         to: "userId",
         rate: n
      },
      ...
   ]
否,您应该使用一个用于递增值的。您也没有返回值,因此函数将超时。返回在云函数中是必需的

您的代码应该如下所示:

exports.updateVotesCount = functions.database.ref('/votes/{id}').onWrite(event => {
   const data = event.data.val();
   return admin.database().ref('/profiles/' + data.to).child('votes_count').transaction(function(votes) {
   if (event.data.exists()){ //If there is a onCreate action (user adds a vote) or use your own snapshot.val()
            return (votes || 0) + 1; //providing a default "0" value if there is no value
        }else{ // if there is a onDelete action (user removes avote)
            return (votes || 1) - 1; //providing a default "1" value if there is no value
     }
  })
})

然而,我无法测试代码,但我认为它应该可以工作。。。请注意,当用户向给定路径添加值时,该值将增加,而当用户在给定路径上删除时,该值将减少,但您可以像我在示例中所说的那样轻松地进行更改。

非常感谢,这似乎是一个很大的进步,现在我可以使用事务正确地更新它,唯一的一点是函数正在控制台中打印“错误序列化返回值:TypeError:将循环结构转换为JSON”。我不知道为什么,因为“投票”总是一个浮动值。@AlejandroMorán O boy如果你能纠正这个错误,你就是我的英雄。我在Github上问过:还有一个解决办法。。。我认为这是Firebase中的一个bug,应该很快修复。是的,根据这个答案,这似乎是Firebase的bug:返回值是TransactionResult,无法序列化,有一个解决方法。我已经尝试了这个解决方法,它很有效,再次感谢您的帮助。