0

我正在关注喜欢的例子

使用它们的确切结构,但用于不同的目的:

/functions-project-12345
    /db
        /1
            contacts_count: 0
            /contacts
                1: true
                2: true
                3: true

contacts_count在正确的位置创建,虽然由于某种原因,contacts_count一直返回 0

exports.contactsCount = functions.database.ref('/db/{userid}/contacts').onWrite(event => {
    return event.data.ref.parent.child('contacts_count').set(event.data.numChildren());
});

我还尝试在 /db/{userid}/contacts/{id} 设置触发器,在阅读了所有文档之后,我似乎仍然无法让它返回正确的计数。

事实上,具有与 likes 示例中完全相同的结构:

/functions-project-12345
    /posts
        /key-123456
            likes_count: 32
            /likes 
                user123456: true
                user456789: true
                user786245: true

并在服务器上运行:

exports.countlikes = functions.database.ref('/posts/{postid}/likes').onWrite(event => {
  return event.data.ref.parent.child('likes_count').set(event.data.numChildren());
});

仍然将0保存到likes_count

event.dataevent.data.numChildren()/db/{userid}/contacts 节点的引用,对吗?

4

1 回答 1

2

2017 年 4 月 13 日更新:以下解决方案仅在您可以保证仅添加子节点(未删除或更改)并且不处理被删除的计数节点时才有效。如需更强大的解决方案,请查看repo中更新的子计数示例firebase/functions-samples

我不确定你的代码到底出了什么问题(我刚刚测试了这个例子,它对我有用),但是做同样事情的更安全的方法是使用transaction()而不是 set()。修改您提供的示例代码,如下所示:

exports. contactsCount = functions.database.ref('/db/{userid}/contacts')
  .onWrite(event => {
    var contactCountRef = event.data.ref.parent.child('contacts_count');
    return contactCountRef.transaction(function(currentCount) {
      return (currentCount || 0) + 1;
    });
  });

此代码应该对您有用,因为它不依赖于您遇到的任何问题,numChildren()并且它具有额外的好处,即可以避免官方示例中存在的竞争条件。我们实际上正在努力更新示例以正确使用事务。

于 2017-03-12T23:26:52.730 回答