【问题标题】:How to Sort and Filter Firebase Realtime Database with Cloud Functions, Node.js & Javascript for 'High Score' Leaderboard如何使用 Cloud Functions、Node.js 和 Javascript 对 Firebase 实时数据库进行排序和过滤以获得“高分”排行榜
【发布时间】:2020-08-17 07:42:16
【问题描述】:

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

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

我想做的事:

在更新任何用户下的 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 个新的键值对。但是什么也没发生。

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

【问题讨论】:

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


    【解决方案1】:

    您不会从代码的顶层返回任何内容,这意味着 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 继续运行,直到查询和后续更新完成。

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

    【讨论】:

    • 感谢您的澄清,承诺现在更有意义,我可以在您提供的更正代码中看到模式。但是,它似乎仍然没有达到预期的效果。该函数运行(如我的 firebase 日志中所示),但在 forEach 循环中调用的更新无效。你还有什么可以看到我失踪的吗?感谢您的意见。一旦我得到它的工作,我可以更好地学习和理解它,并从那里进一步调整它以满足我的需求。
    猜你喜欢
    • 1970-01-01
    • 2019-03-28
    • 1970-01-01
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多