jos*_*osh 124 database count firebase
你可以通过孩子来计算
firebase_node.once('value', function(snapshot) { alert('Count: ' + snapshot.numChildren()); });
Run Code Online (Sandbox Code Playgroud)
但我相信这会从服务器中获取该节点的整个子树.对于巨大的列表,这似乎是RAM和延迟密集型.有没有办法获取计数(和/或子名称列表)而不取出整个事物?
And*_*Lee 93
您提供的代码片段确实会加载整个数据集,然后将其计入客户端,这对于大量数据来说可能非常慢.
Firebase目前无法在不加载数据的情况下对子项进行计数,但我们确实计划添加它.
目前,一种解决方案是维护子项数的计数器,并在每次添加新子项时更新它.您可以使用事务来计算项目,例如此代码跟踪upvodes:
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;
});
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅https://www.firebase.com/docs/transactions.html
更新: Firebase最近发布了云功能.使用云功能,您无需创建自己的服务器.您只需编写JavaScript函数并将其上传到Firebase即可.Firebase将负责在事件发生时触发功能.
例如,如果你想计算upvotes,你应该创建一个类似于这个的结构:
{
"posts" : {
"-JRHTHaIs-jNPLXOQivY" : {
"upvotes_count":5,
"upvotes" : {
"userX" : true,
"userY" : true,
"userZ" : true,
...
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后编写一个javascript函数来增加upvotes_count对upvotes节点的新写入.
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());
});
Run Code Online (Sandbox Code Playgroud)
另外,另一个计算帖子的例子是:https: //github.com/firebase/functions-samples/blob/master/child-count/functions/index.js
在火力文档已经改变所以不是event我们现在有change和context.
给出的示例抛出一个错误抱怨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);
});
Run Code Online (Sandbox Code Playgroud)
```
Ale*_*isz 34
这是游戏中的一个晚了,因为其他几个人已经很好地回答了,但我将分享如何实现它.
这取决于Firebase REST API提供shallow=true参数的事实.
假设你有一个post对象,每个对象可以有一个comments:
{
"posts": {
"$postKey": {
"comments": {
...
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
你显然不想获取所有评论,只需要获取评论数量.
假设您有帖子的密钥,您可以发送GET请求
https://yourapp.firebaseio.com/posts/[the post key]/comments?shallow=true.
这将返回键值对的对象,其中每个键是注释的键,其值为true:
{
"comment1key": true,
"comment2key": true,
...,
"comment9999key": true
}
Run Code Online (Sandbox Code Playgroud)
此响应的大小远小于请求等效数据,现在您可以计算响应中的键数以找到您的值(例如commentCount = Object.keys(result).length).
这可能无法完全解决您的问题,因为您仍在计算返回的键数,并且您不一定在更改时订阅该值,但它确实大大减少了返回数据的大小,而无需对您的任何更改架构.
ppe*_*rin 22
随时保存计数 - 并使用验证来强制执行.我一起攻击了这个 - 为了保持一个独特的选票数和不断上升的数量!但这次我测试了我的建议!(尽管有剪切/粘贴错误!).
这里的'技巧'是使用节点优先级作为投票计数...
数据是:
vote/$ issueBeingVotedOn/user/$ uniqueIdOfVoter = thisVotesCount,priority = thisVotesCount vote/$ issueBeingVotedOn/count ='user /'+ $ idOfLastVoter,priority = CountofLastVote
,"vote": {
".read" : true
,".write" : true
,"$issue" : {
"user" : {
"$user" : {
".validate" : "!data.exists() &&
newData.val()==data.parent().parent().child('count').getPriority()+1 &&
newData.val()==newData.GetPriority()"
Run Code Online (Sandbox Code Playgroud)
用户只能投票一次&& count必须比当前计数高一个&&数据值必须与优先级相同.
}
}
,"count" : {
".validate" : "data.parent().child(newData.val()).val()==newData.getPriority() &&
newData.getPriority()==data.getPriority()+1 "
}
Run Code Online (Sandbox Code Playgroud)
count(真正的最后一个选民) - 投票必须存在并且其计数等于newcount,&& newcount(优先级)只能增加一个.
}
}
Run Code Online (Sandbox Code Playgroud)
测试脚本以添加不同用户的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>
Run Code Online (Sandbox Code Playgroud)
这里的"风险"是投票,但计数未更新(黑客或脚本失败).这就是为什么投票具有独特的"优先级" - 脚本应该首先确保没有优先级高于当前计数的投票,如果它应该在完成该事务之前完成该事务 - 让客户清理为你:)
在开始之前需要使用优先级初始化计数 - 伪造不允许您这样做,因此需要存根脚本(在验证激活之前!).
| 归档时间: |
|
| 查看次数: |
83185 次 |
| 最近记录: |