Firebase orderByChild () не упорядочивает численно - PullRequest
0 голосов
/ 03 января 2019

Я пытаюсь упорядочить пользовательские баллы с помощью метода запроса 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 () возвращает моих пользователей в том порядке, в котором они находятся в базе данных, а НЕ по их точечным значениям.

UPDATE Для тех, кто в будущем, возможно, будет бороться с этим, то, как я исправил это (с помощью Фрэнка), вместо установки идентификатора пользователя как части пути JSON, я выдвинул идентификатор как один из дочерних элементов:

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

Это позволило выполнить запрос без ошибок.

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Поскольку я не совсем уверен, в чем проблема, я настроил небольшой собственный тест для вас.

JSON:

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

Live 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

Таким образом, эти два узла в местоположении, которые я запрашиваю в порядке их значений точек.

0 голосов
/ 03 января 2019

Дело в том, что вы используете метод .once(), а запросы Firebase Realtime работают только с методом .on(), как вы можете видеть в справочных документах . Поэтому изменение ссылок, где вы используете .orderByChild() на .on(), должно заставить его работать.

Также я советую вам узнать, как лучше структурировать вашу базу данных, ваш код настолько сложен для чего-то, что должно быть простым, и вы делаете 3 вызова в Firebase (или 3 уровня, поскольку есть forEach со многими другие запросы). Вы должны изучить, как лучше работать с Firebase Realtime, иначе ваш код будет становиться все труднее и труднее обслуживать и читать.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...