Firebase orderByChild()不在数字上排序

时间:2019-01-03 08:24:57

标签: typescript firebase ionic-framework firebase-realtime-database

我正在尝试通过Firebase的orderByChild()查询方法对用户点进行排序。我似乎无法全神贯注,因为我是Typescript / Firebase新手,所以我一直在使用很多示例代码。

我的Firebase JSON看起来像这样:

{
  "users" : {         
    "hJfEgXkyaKPckchL3kx8rpZ58Ew2" : {
      "-LV6c8E5rRD4_mQqsb6Q" : {
        "grade" : 11,
        "name" : "Lin Manuel Miranda",
        "points" : 100
      }
    },
    "mlIBrdjT8CfIURQEAhLFPzzUFQg1" : {
      "-LV7I6d8LeuWFLH5MRKy" : {
        "grade" : 12,
        "name" : "Emily Blunt",
        "points" : 20
      }
    }
 // "userID" : {
 //    "-firebase-generated-id": {
 //        "grade" : number,
 //        "name" : string,
 //        "points" : number
 //    }
 //  }
  }
}

我的代码虽然有点混乱,但运行方式却是这样,因为我需要检索特定的键来引用数据库...所以,我试图将所有信息推入一个新数组中,然后显示html中的数组。

// ts file

export class Tab1Page {
  name: string;
  grade: number;
  points: number;
  empList: Array<{name: string, grade: number, points: number}> = [];

  constructor(
    private db: AngularFireDatabase
  ) {
        // the variable pkey here is a reference to the userID
        const keyRef = firebase.database().ref('/users/' + pkey);
        const ref2 = keyRef.orderByChild('points').limitToLast(7);

        ref2.once('value').then(function(snap2) {
          snap2.forEach(function (childSnap2) {
            const key = childSnap2.key;
            const List = this.empList;
            const firebaseRef = firebase.database().ref('/users/' + pkey + '/' + key);
            
            firebaseRef.once('value').then(function(snapshot) {
              const name = snapshot.val().name;
              const grade = snapshot.val().grade;
              const points = snapshot.val().points;
              List.push({
                name: name,
                grade: grade,
                points: points
              });
            });
          });
        });
      });
    });
  }

}

问题是,无论我如何编辑代码,orderByChild()查询都将按照用户在数据库中的顺序返回我的用户,而不是按其点值返回。

更新 对于那些将来也可能会为此感到挣扎的人,我(在弗兰克的帮助下)修复它的方式不是将用户ID设置为JSON路径的一部分,而是将ID推送为以下子项之一:< / p>

{
  "users" : {
    "-LVL5EWo3MBnLdAv0fFf" : {
      "ID" : "g4V3ZmBRJfcN2WSeoSPuPbxl3o72",
      "grade" : 11,
      "name" : "Caroline Choi",
      "points" : 10
    },
    "-LVL69jiTxb5MprLpjrK" : {
      "ID" : "21XBQvWXtuayo1ZxxmS566phDv13",
      "grade" : 12,
      "name" : "Emily Blunt",
      "points" : 0
    }
  }
}

这可以使查询运行没有错误。

2 个答案:

答案 0 :(得分:0)

情况是,您正在使用.once()方法,而Firebase Realtime查询仅适用于.on()方法,如您在reference docs中所见。因此,将您使用.orderByChild().on()的引用更改为有效。

我还建议您学习如何以更好的方式构建数据库,您的代码因必须简单而复杂,并且您要对Firebase进行3次调用(或3个级别,因为forEach包含许多其他要求)。您必须考虑学习如何更好地使用Firebase Realtime,否则您的代码将变得越来越难以维护和阅读。

希望这会有所帮助。

答案 1 :(得分:0)

由于我不太确定问题出在哪里,因此我对自己进行了一些测试,供您查看。

JSON:

{
  "-LV6c8E5rRD4_mQqsb6Q" : {
    "grade" : 11,
    "name" : "Lin Manuel Miranda",
    "points" : 100
  },
  "-LV6c8E5rRD4_mQqsb6Z" : {
    "grade" : 42,
    "name" : "Frank van Puffelen",
    "points" : 80
  }
}

实时JSON:https://stackoverflow.firebaseio.com/54018652/users/hJfEgXkyaKPckchL3kx8rpZ58Ew2.json?print=pretty

代码:

var ref = firebase.database().ref("/54018652");

var keyRef = ref.child("users/hJfEgXkyaKPckchL3kx8rpZ58Ew2");
var ref2 = keyRef.orderByChild('points').limitToLast(7);

ref2.once('value').then(function(snap2) {
  snap2.forEach(function (childSnap2) {
    var key = childSnap2.key;
    var points = childSnap2.child("points").val();
    console.log(key+": "+points);
  });
});

工作代码:https://jsbin.com/ceyejil/edit?js,console

当我针对此JSON运行此代码时,它会打印:

  

-LV6c8E5rRD4_mQqsb6Z:80

     

-LV6c8E5rRD4_mQqsb6Q:100

这就是我要查询的位置下的两个节点,按照它们的点值顺序。