javascript - 如何使用云函数、Node.js 和 Javascript 对 Firebase 实时数据库进行排序和筛选 'High Score' 排行榜

标签 javascript node.js firebase-realtime-database google-cloud-functions filtering

我已经研究和试错好几天了,但没能取得任何成果。在测试中,我在 Firebase Realtime 数据库中创建了一些测试 Node ,以便尝试计算出该函数的逻辑。我的文件树如下所示:

enter image description here

为了简单地让基础知识发挥作用,我在 TestUsers Node 下创建了一些用户,每个用户都有一个非常简单的 Statistics 子结构,然后是一个 球体值。

我正在尝试做什么:

在更新任何用户下的 orbs 值时,我想编写(好吧,技术上“更新”)Output/firstPlace 子项以包含用户名和前 3 位用户的球体数量(在 TestUsers 下的所有用户中具有最高的球体数量。

看起来非常简单,相信我,我知道有大量关于排序和过滤 Firebase 实时数据库数据的文档,但我在阅读该文档几天后仍无法将它们拼凑在一起。

我正在使用 VS Code 编写函数并将其部署到我的 Firebase 项目中。

我为尝试执行上述操作而编写的函数是这样的:

//Define a new function with a base path and set it to run when a child of this path is changed
exports.testTopPlayers1 = functions.database.ref('/TestUsers/{user}/Statistics').onUpdate(_ => { 

    var allPlayersRef = admin.database().ref('/TestUsers/{user}'); //When this function runs, assign a new path of all users

        //Get a snapshot of the top 3 users with the highest orb count
        allPlayersRef.orderByChild('orbs').limitToLast(3).once('value', (snap) => { 

          //For each child from the above snap (should be 3)...
          snap.forEach((child, context) => {

                const username = context.params.user; //Assign the username to a const
                const afterOrbAmount = child.after.val();
                const orbAmount = afterOrbAmount.orbs; //Assign the number of orbs to a const

                //Return (Promise?) by updating the data in '/Output/firstPlace' with the username and orb amount.
                return admin.database().ref('/Output/firstPlace').update({[username]: [orbAmount]});
          });
  })
})

我希望使用 .forEach 时,它应该运行对 '/Output/firstPlace 部分的写入 3 次,从而有效地为我提供 3 个新的键值对。但什么也没发生。

根据我正在尝试做的事情,您可以更正我的代码或向我展示在后端实现这样的高分排序的正确方法吗?

最佳答案

您不会从代码的顶层返回任何内容,这意味着 Cloud Functions 无法知道您的代码何时完成。因此:它会在最后一个 } 之后停止您的代码,即数据库读取完成之前。

您的代码应如下所示:

exports.testTopPlayers1 = functions.database.ref('/TestUsers/{user}/Statistics').onUpdate(_ => { 

    var allPlayersRef = admin.database().ref('/TestUsers/{user}'); //When this function runs, assign a new path of all users

    let query = allPlayersRef.orderByChild('orbs').limitToLast(3)
    return query.once('value').then((snap) => { 
        let promises = [];
        snap.forEach((child, context) => {
            const username = context.params.user;
            const afterOrbAmount = child.after.val();
            const orbAmount = afterOrbAmount.orbs;

            promises.push(admin.database().ref('/Output/firstPlace').update({[username]: [orbAmount]}));

        });
        return Promise.all(promises);
    })
})

您的代码中可能存在更多问题,但这可以确保您的云函数将继续运行,直到查询和后续更新完成。

我强烈建议您学习以下内容,以了解有关如何控制云函数何时终止的更多信息:

关于javascript - 如何使用云函数、Node.js 和 Javascript 对 Firebase 实时数据库进行排序和筛选 'High Score' 排行榜,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61565829/

相关文章:

javascript - 如何用Javascript制作表格边框动画?

javascript - 包装 JavaScript 函数引用

ios - Firebase:是否可以更新多个父级中的单个子级?

javascript - 在环回生成的代码中放置远程 Hook (beforeRemote、afterRemote)代码的位置

javascript - 尝试用javascript解析json源

node.js - 在生产入口文件中使用 babel-polyfill

javascript - 渲染数据前添加条件和排序

swift - 使用 Firebase 从查询中快速检索数据

node.js - Visual Studio Code 集成终端 : http-server : The term 'http-server' is not recognized

Javascript 解析 JSON 错误,但在验证器中工作正常