Как отсортировать / отфильтровать базу данных Firebase Realtime с помощью запроса в Javascript - PullRequest
0 голосов
/ 03 мая 2020

Мне трудно понять, почему этот простой запрос не дает ожидаемых результатов.

В моей базе данных Firebase в реальном времени моя структура выглядит следующим образом:

enter image description here

Довольно просто, верно? Затем у меня есть облачная функция, которая запускается всякий раз, когда я вручную изменяю одно из значений 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());
      })

Также очень проста, я думаю. В обычном engli sh я ожидаю, что эта функция будет выполнять следующее: «При изменении любого из значений orbs запустите эту функцию, чтобы отсортировать всех пользователей по значению их шаров (от низшего к наибольшему) и принять новый DataSnapshot только данных последних 2 пользователей (пользователей с наибольшим числом шаров) ".

Когда я печатаю на консоль, я ожидаю увидеть данные из User3 & User6 потому что у них наибольшее количество шаров ... но вместо этого, похоже, сортировка по имени пользователя (User5 & User6) или просто не сортировка вообще. Вот вывод журнала:

enter image description here

, который явно не сортируется по тому, что я определяю в своем запросе.

Может быть, я Я упускаю что-то очевидное, но я достаточно долго на это смотрю ... надеюсь, что кто-то обнаружит ошибку в моей функции в отношении того, как она сортируется.

Я ценю помощь!

Ответы [ 2 ]

2 голосов
/ 03 мая 2020

Вы ищете:

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

Обратите внимание, что вы также захотите использовать once() вместо on():

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

You ' Я также хочу удалить это console.log вокруг snap.val(), поскольку console.log() ничего не возвращает.


Наконец: когда вы вызываете .val() на снимке, вы конвертируете его к парам ключ-значение и потерять информацию о заказе. Если вы хотите сохранить порядок, вы можете использовать forEach:

return query.once('value').then((snap) => {
    let results = [];
    snap.forEach((player) => {
        results.push( {key: snap.key, ...snap.val() }
    });
    return results;
})
0 голосов
/ 03 мая 2020

Благодаря подробному ответу Фрэнка, я смог понять, что должно произойти, и отлично справился с незначительными изменениями.

С точными изменениями, предложенными Фрэнком, мой вывод в консоль Firebase выглядел следующим образом :

enter image description here

Это намного лучше, чем то, что я смог получить до сих пор, но он все еще не отображал точные данные, которые я хотел использовать. Я не интересовался ключом snap (который является узлом TestUsers верхнего уровня), а скорее мне нужен ключ player, который предоставляет имя пользователя, ответственное за высокий балл.

Далее, вместо того, чтобы получить [объект] для значений сфер, мне нужно было получить действительное значение сфер, поэтому мне пришлось погрузиться в дочерние элементы каждого player объекта, чтобы получить это значение.

Это моя измененная функция облака во всей ее красе. Lol:

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 такой:

enter image description here

Это именно то, что я преследовал и теперь могу продолжать: D

...