使用函数在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。它可以也应该被优化,这个解决方案只是一个很好的起点。