2017-04-12 126 views
1

我在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功能

回答

0

好吧,我想通了。下面的代碼是第一個工作解決方案。

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。它可以也應該被優化,這個解決方案只是一個很好的起點。

相關問題