繁体   English   中英

如何使用云函数对 Firebase 实时数据库、Node.js 和 Javascript 进行排序和过滤以获得“高分”排行榜

[英]How to Sort and Filter Firebase Realtime Database with Cloud Functions, Node.js & Javascript for 'High Score' Leaderboard

几天来我一直在研究和试错,但没有任何工作。 在测试中,我在我的 Firebase 实时数据库中创建了一些测试节点,以尝试计算函数的逻辑。 我的文件树如下所示:

在此处输入图像描述

为了简单地让基础工作正常,我在TestUsers节点下创建了几个用户,每个用户都有一个非常简单的Statistics子结构,然后是一个orbs值。

我正在尝试做的事情:

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

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

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

我写的 function 尝试执行上述操作是这样的:

//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);
    })
})

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM