使用函数在Firebase数据库中订购节点的子节点
问题描述:
我在firebase数据库中有一个排行榜。我为score和userName设置了.indexOn
规则。我给它添加记录,获得前十名,这些速度很快,很容易在客户端实现。使用函数在Firebase数据库中订购节点的子节点
但是检索当前用户的等级在客户端可能会非常慢,因为我必须获取排行榜节点的子节点的完整列表并计数记录,直到找到用户记录为止......此排行榜可能会起来到10万条记录。更何况,这与巨大的网络流量。
我想使用firebase函数在插入记录时对记录进行排序和排名,这样我就可以尽可能保持网络流量。
我的结构是这样的:
"leaderboard": {
"user_id_xxxx":
{
"uid": "user_id_xxxx",
"userName" : "someone",
"score": 99999
"rank": 1
},
"user_id_xxxy":
{
"uid": "user_id_xxxy",
"userName" : "otherone",
"score": 99998
"rank": 2
}
}
于是我想出了一个代码片段,但我不知道如何来订购吧:
var functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var dbRef = functions.database.ref('/leaderboard');
exports.dbRefOnWriteEvent = dbRef.onWrite(event => {
const parentRef = event.data.ref.parent();
return parentRef.once('value').then(snapshot => {
var i = 1;
const updates = {};
snapshot.forEach(function(child) {
child.rank = i;
i++;
});
return parentRef.update(updates);
});
});
我明白任何建议和帮助,我还在学习node.js和Firebase功能
答
好吧,我想通了。下面的代码是第一个工作解决方案。
var functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var dbRef = functions.database.ref('/leaderboard');
exports.dbRefOnWriteEvent = dbRef.onWrite(event => {
var ref = admin.database().ref("/leaderboard");
ref.orderByChild("score").once("value", function(dataSnapshot) {
var i = 0;
dataSnapshot.forEach(function(childSnapshot) {
var childRef = childSnapshot.ref;
var r = (dataSnapshot.numChildren() - i);
childRef.update({rank: r},function(error) {
if (error != null)
console.log("update error: " + error);
});
i++;
});
});
});
你必须建立这样一个索引规则,使其工作:
"leaderboard": {
".indexOn": [ "/score", "/rank" ]
}
不知道为什么它需要的斜线字符,但它并没有发挥作用。
简短说明:我已将onWrite
触发器添加到排行榜,每次更新时forEach
都会运行并更新rank
。它可以也应该被优化,这个解决方案只是一个很好的起点。