При использовании queryOrderedByChild для получения списка лучших результатов, как я могу отображать связанные результаты в правильном порядке? - PullRequest
1 голос
/ 12 мая 2019

Мое приложение имеет таблицу лучших результатов, в которой используются .queryOrdered (byChild: "userHighScore") и .queryLimited (toLast: 100), чтобы получить 100 самых высоких результатов:

func getTopScores() {
    var scores = [String]()

    self.reference
        .child("users")
        .queryOrdered(byChild: "userHighScore")
        .queryLimited(toLast: 100)
        .observeSingleEvent(of: .value, with: { (snapshot) in

            for child in snapshot.children.reversed() {

                if let dataSnapshot = child as? DataSnapshot, let user = dataSnapshot.value as? [String:AnyObject] {

                    if let userHighScore = user["userHighScore"] as? Int {
                        var stringToAppend = "\(scores.count+1). "


                        if let userName = user["userName"] as? String {
                            stringToAppend += " \(userName)   •  \(userHighScore)"
                        }

                        scores.append(stringToAppend)
                    }
                }
            }
        })
    }

Проблема заключается в том, когдаесть счет ничьи

В идеале, первый пользователь, получивший этот балл, должен быть выше других с таким же баллом в таблице (а самый последний пользователь, получивший этот балл, был бы самым низким из тех, у кого такой же балл).

Однако в таблице отображаются результаты с одинаковыми счетами в том же случайном порядке, что и в базе данных реального времени Firebase.

Существует ли способ сортировки связанных результатов в хронологическом порядке?

Я крутил свои колеса на этом в течение многих часов.Заранее спасибо за любую помощь!

Ответы [ 2 ]

6 голосов
/ 13 мая 2019

В идеале, первый пользователь, получивший этот балл, должен быть выше остальных с таким же баллом в таблице

По сути, вы пытаетесь заказать два свойства: userHighScore и userHighScoreTimestamp (я придумал имя, так как вы не указали его в своем вопросе). База данных Firebase Realtime может запрашивать только одно свойство. См. Запрос на основе нескольких предложений where в Firebase

.

То, что вы можете сделать, - это определить дополнительное свойство, которое объединяет значения высокой оценки и достигнутой отметки времени:

users: {
  derenceUid: {
    userHighScore: 42,
    userHighScoreTimestamp: 1557695609344,
    userHighScore_Timestamp: "000042_1557695609344",
  },
  dougUid: {
    userHighScore: 31,
    userHighScoreTimestamp: 1557609264895,
    userHighScore_Timestamp: "000005_1557609264895",
  },
  pufUid: {
    userHighScore: 42,
    userHighScoreTimestamp: 1557695651730,
    userHighScore_Timestamp: "000042_1557695651730",
  }
}

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

ref.queryOrdered(byChild: "userHighScore_Timestamp"). queryLimited(toLast: 1)

Стоит отметить, что я набрал шесть цифр, чтобы набрать высокий балл у пользователя. Это необходимо, поскольку Firebase проведет лексикографическое сравнение этих клавиш, и без отступа "5_1557609264895" будет больше, чем "42_1557695609344". Вы должны выяснить, сколько цифр может содержать ваш максимальный счет. В моем примере я использовал 6 цифр, поэтому он может содержать до 1 миллиона.

1 голос
/ 13 мая 2019

В идеале, то, что вам нужно, это orderByChild для двух значений: счет и дата.Насколько я знаю, база данных Firebase Realtime не поддерживает это.Я мог бы предложить два варианта:

  1. Хранить оценки не в виде строк, а в виде объектов, включая два значения: «Оценка» и «Отметка времени».Затем, когда вы получите список объектов оценки, сортируйте их на стороне клиента по оценке, а затем снова сортируйте связи по дате.
  2. Добавьте небольшое значение к каждой оценке на основе даты.Значение должно быть достаточно маленьким, чтобы оно не влияло на оценку.Например: подсчитайте количество минут от эпохи (сейчас это около 25961), разделите на 1 миллион, должно получиться 0,025961.Добавление этого к каждому вашему баллу не изменит сортировку баллов и поможет сохранить их хронологию.Только не забудьте избавиться от дробной части при представлении баллов.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...