Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.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
Database 在Firebase中,是否有一种方法可以在不加载所有节点数据的情况下获取节点的子节点数?_Database_Firebase_Count - Fatal编程技术网

Database 在Firebase中,是否有一种方法可以在不加载所有节点数据的情况下获取节点的子节点数?

Database 在Firebase中,是否有一种方法可以在不加载所有节点数据的情况下获取节点的子节点数?,database,firebase,count,Database,Firebase,Count,你可以通过电话了解孩子的人数 firebase_node.once('value', function(snapshot) { alert('Count: ' + snapshot.numChildren()); }); 但我相信这会从服务器获取该节点的整个子树。对于庞大的列表,这似乎是RAM和延迟密集型的。有没有一种方法可以在不获取全部数据的情况下获取计数(和/或子名称列表)?您提供的代码片段确实加载了整个数据集,然后在客户端对其进行计数,这对于大量数据来说可能非常慢 Firebase目前没

你可以通过电话了解孩子的人数

firebase_node.once('value', function(snapshot) { alert('Count: ' + snapshot.numChildren()); });

但我相信这会从服务器获取该节点的整个子树。对于庞大的列表,这似乎是RAM和延迟密集型的。有没有一种方法可以在不获取全部数据的情况下获取计数(和/或子名称列表)?

您提供的代码片段确实加载了整个数据集,然后在客户端对其进行计数,这对于大量数据来说可能非常慢

Firebase目前没有在不加载数据的情况下计算子级的方法,但我们确实计划添加它

目前,一种解决方案是维护一个子级数计数器,并在每次添加新子级时更新它。您可以使用事务对项目进行计数,如下代码所示:

var upvotesRef = new Firebase('https://docs-examples.firebaseio.com/android/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes');
upvotesRef.transaction(function (current_value) {
  return (current_value || 0) + 1;
});
有关详细信息,请参阅

更新: Firebase最近发布了云功能。使用云功能,您无需创建自己的服务器。您只需编写JavaScript函数并将其上载到Firebase即可。Firebase将负责在事件发生时触发功能

例如,如果要计算累积投票数,则应创建类似于以下结构的结构:

{
  "posts" : {
    "-JRHTHaIs-jNPLXOQivY" : {
      "upvotes_count":5,
      "upvotes" : {
      "userX" : true,
      "userY" : true,
      "userZ" : true,
      ...
    }
    }
  }
}
然后编写一个javascript函数,在对
upvoces
节点进行新的写入时,增加
upvoces\u计数

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.countlikes = functions.database.ref('/posts/$postid/upvotes').onWrite(event => {
  return event.data.ref.parent.child('upvotes_count').set(event.data.numChildren());
});
你可以阅读这本书,知道如何阅读

此外,另一个计算员额的例子如下:

2018年1月更新 事件已更改,因此我们现在有
更改
上下文

给定的示例抛出一个错误,抱怨
event.data
未定义。这种模式似乎效果更好:

exports.countPrescriptions = functions.database.ref(`/prescriptions`).onWrite((change, context) => {
    const data = change.after.val();
    const count = Object.keys(data).length;
    return change.after.ref.child('_count').set(count);
});

```

在运行时保存计数-并使用验证强制执行计数。我把它拼凑在一起-为了保持一个独特的选票计数和不断出现的计数!。但这一次我已经测试了我的建议!(尽管存在剪切/粘贴错误!)

这里的“技巧”是使用节点优先级作为投票计数

数据如下:

投票/$issueBeingVotedOn/user/$uniqueIdOfVoter=thisvotescont,priority=thisvotescont 投票/$issueBeingVotedOn/count='user/'+$idOfLastVoter,优先级=最后一次投票的计数

,"vote": {
  ".read" : true
  ,".write" : true
  ,"$issue" : {
    "user" : {
      "$user" : {
        ".validate" : "!data.exists() && 
             newData.val()==data.parent().parent().child('count').getPriority()+1 &&
             newData.val()==newData.GetPriority()" 
用户只能投票一次&&计数必须比当前计数高一次&&数据值必须与优先级相同

      }
    }
    ,"count" : {
      ".validate" : "data.parent().child(newData.val()).val()==newData.getPriority() &&
             newData.getPriority()==data.getPriority()+1 "
    }
count(最后一位投票人)-投票必须存在,且其计数等于newcount,&&newcount(优先级)只能增加1

  }
}
测试脚本,以添加不同用户的10张投票(在本例中,id是伪造的,应该是生产中的用户auth.uid)。倒数(i--)10以查看验证失败

<script src='https://cdn.firebase.com/v0/firebase.js'></script>
<script>
  window.fb = new Firebase('https:...vote/iss1/');
  window.fb.child('count').once('value', function (dss) {
    votes = dss.getPriority();
    for (var i=1;i<10;i++) vote(dss,i+votes);
  } );

function vote(dss,count)
{
  var user='user/zz' + count; // replace with auth.id or whatever
  window.fb.child(user).setWithPriority(count,count);
  window.fb.child('count').setWithPriority(user,count);
}
</script>

window.fb=newfirebase('https:…vote/iss1/');
window.fb.child('count')。一次('value',函数(dss){
投票数=dss.getPriority();

对于(var i=1;i这在游戏中已经有点晚了,因为其他几个人已经很好地回答了这个问题,但我将分享如何实现它

这取决于提供了一个
shallow=true
参数

假设您有一个
post
对象,每个对象都可以有许多
注释

{
 "posts": {
  "$postKey": {
   "comments": {
     ...  
   }
  }
 }
}
显然,您不想获取所有注释,只想获取注释的数量

假设您有帖子的密钥,您可以向发送
GET
请求
https://yourapp.firebaseio.com/posts/[发布键]/comments?shallow=true

这将返回一个键值对对象,其中每个键都是注释的键,其值为
true

{
 "comment1key": true,
 "comment2key": true,
 ...,
 "comment9999key": true
}
此响应的大小比请求等效数据小得多,现在您可以计算响应中的键数以查找您的值(例如commentCount=
Object.keys(result).length


这可能无法完全解决您的问题,因为您仍在计算返回的键数,并且您不必在值发生变化时订阅该值,但它确实大大减少了返回数据的大小,而无需对模式进行任何更改。

编写云函数以更新节点计数

// below function to get the given node count.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.userscount = functions.database.ref('/users/')
    .onWrite(event => {

      console.log('users number : ', event.data.numChildren());


      return event.data.ref.parent.child('count/users').set(event.data.numChildren());
    }); 
参考:

根--| |-用户(此节点包含所有用户列表) |
|-计数 |-用户搜索:
(此节点由云函数随用户数动态添加)

您是否添加过对该功能的支持?不过,交易中的客户端计数器是否安全?似乎很容易被黑客攻击以人为增加计数。这可能对投票系统有害。+++如果能够在不产生转移成本的情况下获得计数,那就太好了。是否添加了该功能?有关此功能路线图的任何消息?谢谢太棒了!!!但是冲突会发生什么?例如,两个人同时投票?理想情况下,你希望自动解决这一问题,而不是放弃他们的一张选票…也许在交易中进行投票?嗨,Josh,从逻辑上讲,真正的投票只有在前一张选票已经投下的情况下才会失败,但总投票数尚未更新.我的第二段到最后一段谈到了这一点-无论如何,我只会为以前的选民投票做全部更新(每次)-如果不需要,那又怎样?然后这个投票会更新。只要投票正常。如果“total”更新失败,下一个投票人会修复它,那么再次-那又怎样?我真的很想说“count”节点应该是“last previous vote”节点-所以每个投票人/客户端更新/修复/修复该节点/值,然后添加自己的投票-(让下一位投票人更新总数以包括“本次”投票).--如果你明白我的意思…可能会让这个答案成为公认的答案,因为shall=true是之前答案的新添加。我自己还没有时间研究它,所以我会等几天看看人们怎么想…shall可能是目前最好的选择,但它不会随着压缩而返回,并且会变得非常缓慢,并且体验到r如果注释键没有布尔值,而是有c,则为大数据集