.nu​​mChildren()总是返回0

时间:2017-03-11 18:58:47

标签: firebase firebase-realtime-database google-cloud-functions

我正在关注likes示例

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

/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}设置触发器,在阅读完所有文档之后,我似乎无法让它返回正确的计数。

实际上,具有与例子中完全相同的结构:

/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.data {/ 1}}对/ db / {userid} / contacts节点的引用,对吗?

1 个答案:

答案 0 :(得分:2)

更新04/13/17:以下解决方案仅在您可以保证仅添加(未删除或更改)子节点且不处理要删除的计数节点时才有效。要获得更强大的解决方案,请查看更新后的child count example in the firebase/functions-samples repo

我不确定您的代码究竟出了什么问题(我刚刚测试了这个示例,它对我有用),但更安全的方法是使用transaction()代替组()。修改您提供的示例代码,如下所示:

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()遇到的任何问题,并且它具有额外的好处,即可以安全地避免官方样本中存在的竞争条件。我们实际上正在努力让样本更新以正确使用事务。