【问题标题】:How to Sort/Filter Firebase Realtime Database with Query in Javascript如何使用 Javascript 中的查询对 Firebase 实时数据库进行排序/过滤
【发布时间】:2020-05-03 03:36:48
【问题描述】:

我很难理解为什么这个简单的查询没有给我预期的结果。

在我的 Firebase 实时数据库中,我的结构如下所示:

很简单,对吧?接下来,我有一个云功能,只要我手动更改任何用户下的orbs 值之一,它就会运行。这是我的功能:

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

    const allPlayersRef = admin.database().ref('/TestUsers');

    const query = allPlayersRef.orderByChild('orbs').limitToLast(2)
      return query.on('value', (snap, context) => {

          return console.log(snap.val());
      })

我认为也非常简单。在普通英语中,我期望该函数执行的是:“当任何 orbs 值发生更改时,运行此函数以按所有用户的 orbs 值(从最低到最高)排序并获取新的 DataSnapshot仅最后 2 个用户的数据(orb 数量最多的用户)”。

当我打印到控制台时,我希望看到来自 User3User6 的数据,因为它们的球体数量最多......但它似乎是按用户名排序的 (@987654330 @ & User6) 或者根本不排序。这是日志输出:

这显然没有按照我在查询中定义的内容进行排序。

也许我遗漏了一些明显的东西,但我已经盯着它看够久了......希望有人能在我的函数中发现关于它如何排序的错误。

感谢您的帮助!

【问题讨论】:

    标签: javascript firebase-realtime-database google-cloud-functions


    【解决方案1】:

    您正在寻找:

    allPlayersRef.orderByChild('Statistics/orbs').limitToLast(2)
    

    请注意,您还需要使用once() 而不是on()

    return query.once('value').then((snap) => {
        return snap.val();
    })
    

    您还需要删除snap.val() 周围的console.log,因为console.log() 不会返回任何内容。


    最后:当您在快照上调用.val() 时,您会将其转换为键值对并丢失排序信息。如果你想保持顺序,你会想使用forEach

    return query.once('value').then((snap) => {
        let results = [];
        snap.forEach((player) => {
            results.push( {key: snap.key, ...snap.val() }
        });
        return results;
    })
    

    【讨论】:

      【解决方案2】:

      感谢弗兰克的彻底回答,我能够理解需要发生的事情,并通过细微的调整使其完美运行。

      按照 Frank 建议的确切修改,我在 Firebase 控制台中的输出如下所示:

      这比我之前能够制作的要好得多,但它仍然没有显示我想要使用的确切数据。 我对snap 的键(即顶级TestUsers 节点)不感兴趣,但我想要player 的键,它提供了负责高分的用户名。

      接下来,我需要的是球体的实际值,而不是获取球体值的 [对象],因此我必须深入研究每个 player 对象的子对象来获取该值。

      这是我调整后的云功能,非常棒,哈哈:

      exports.testTopPlayers2 = functions.database.ref('/TestUsers/{user}/Statistics').onUpdate(_ => { 
      
          const allPlayersRef = admin.database().ref('/TestUsers');
      
          const query = allPlayersRef.orderByChild('/Statistics/orbs').limitToLast(2)
            return query.once('value').then((snap) => {
      
                let results = [];
      
                snap.forEach((player) => {
      
                    let username = player.key
                    let orbsValue = player.child("Statistics").child("orbs").val()
      
                    results.push( {Player: username, Score: orbsValue } )
                });
      
                console.log(results)
      
                return results;
            })
      })
      

      Firebase 日志的结果是这样的:

      这正是我所追求的,现在可以继续了:D

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-17
        • 1970-01-01
        • 1970-01-01
        • 2018-06-10
        • 2017-09-08
        • 2021-08-28
        • 1970-01-01
        • 2012-02-25
        相关资源
        最近更新 更多