Node.js中Firebase实时数据库orderByChild排序失效求助
问题根源与解决方案
嘿,我一眼就瞅出问题所在了——你完全浪费了orderByChild的排序结果,反而绕回原始节点按数字索引取数据,再加上嵌套的异步监听,顺序不乱才怪!
核心问题分析
当你调用ref.orderByChild('adscore2017').on("value", ...)时,回调里的snap已经是按adscore2017排好序的完整快照了。但你接下来却用for (var i = 1; i <= numOfChildren; i++)去请求ref.child(i),这相当于直接忽略了排序后的结果,从原始未排序的节点里按数字键拉数据,排序功能自然失效。更糟的是,每个path.on("value")都是异步操作,这些回调的执行顺序完全不受你循环的控制,最后拼接出来的speech顺序肯定是混乱的。
修正后的代码
直接遍历排序后的快照子节点就行,Firebase的snapshot.forEach会严格按照排序后的顺序遍历,而且不需要嵌套监听:
const ref = admin.database().ref('/programmelist'); let speech = "The scores are: "; // 监听排序后的查询结果(如果只需一次性获取,建议用once("value")替代on) ref.orderByChild('adscore2017').once("value", function(snap) { // 按排序顺序遍历每个子节点 snap.forEach(function(childSnap) { const itemData = childSnap.val(); // 这里替换成你需要拼接的内容,比如adscore2017的值 speech += `${itemData.adscore2017}, `; }); // 遍历完成后再输出,确保顺序正确 console.log(speech); });
额外注意事项
- 如果不需要实时监听数据变化,用
once("value")比on("value")更合适,避免多次触发回调。 - 确保你的Firebase实时数据库规则中,为
programmelist节点的adscore2017字段配置了索引,否则排序可能不会生效:
{ "rules": { "programmelist": { ".indexOn": "adscore2017" } } }
内容的提问来源于stack exchange,提问作者yatsing
相关产品推荐
相关产品推荐

