Swift Firebase -.queryStarting (atValue :) и .queryEnding (atValue :), возвращающий всех детей - PullRequest
0 голосов
/ 08 апреля 2019

Когда я запрашиваю конкретного ребенка, я получаю все результаты, а не те, которые относятся к тому, что я ищу:

Например, если мой текст поиска начинается с буквы "c", я должен получить только кошку и корову снизу, но по какой-то причине я также получаю быка.

root
  |
  @---users
        |
        @---uid_1000
        |    |--uid: "uid_1000"
        |    |--username: "bull"
        |
        @---uid_2000
        |    |--uid: "uid_2000"
        |    |--username: "cat"
        |
        @---uid_3000
             |--uid: "uid_3000"
             |--username: "cow"

Я подумал, что, возможно, проблема в том, что я, кажется, собираю все на узле пользователей (множественные словари), а затем перебираю словари, которые могут быть проблемой, но потом я понял, что это должны быть только значения имени пользователя, начинающиеся с буква "с", которая должна появляться внутри словарей, а бык должен быть пропущен.

Где я ошибаюсь?

let searchText = "c"

let ref = Database.database().reference().child("users")
    .queryOrdered(byChild: "username")
    .queryStarting(atValue: searchText)
    .queryEnding(atValue: searchText + "\u{f8ff}")

ref?.observeSingleEvent(of: .value, with: { (snapshot) in

    if !snapshot.exists() { return }

    // dictionaries plural
    guard let dictionaries = snapshot.value as? [String: Any] else { return }

    dictionaries.forEach({ (key, value) in

        guard let dict = value as? [String: Any] else { return }
        let user = User(dict: dict)

        let isContained = self.users.contains(where: { (containedUser) -> Bool in
            return user.uid == containedUser.uid
        })

        if !isContained {
            self.users.append(user)
            self.collectionView.reloadData()
        }
})

Обновлено с помощью Json по запросу Фрэнка:

{
  "users" : {
    "1000" : {
      "userId" : "1000",
      "username" : "bull"
    },
    "2000" : {
      "userId" : "2000",
      "username" : "cat"
    },
    "3000" : {
      "userId" : "3000",
      "username" : "cow"
    }
  }
}

Картинка для соответствия. Я исключил 2 других объекта из json, потому что, хотя они появились на моем конце (у меня на самом деле было 5 результатов), я хотел просто сосредоточиться на том, что в вопросе, который является первым 3.

enter image description here

Ответы [ 2 ]

0 голосов
/ 09 апреля 2019

Я не уверен, почему это произошло, но это была очень странная ошибка.

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

У меня было свойство класса с именем blockRef, и в viewWillAppear я инициализировал его с помощью .observe (.value). Этот реф не связан с моими пользователями. Я только проверял, чтобы убедиться, что этот пользователь не заблокирован ни от кого. Каким-то образом, что blockRef повредил мой запрос на пользователей ref.

После того, как я удалил проблему заблокированного обозревателя 1, проблема была решена (в моем собственном проекте я изначально получал 5 результатов, затем после удаления я получал 3, но они все еще были некорректны).

Чтобы исправить проблему, я удалил инициализацию ref экземпляра

let ref = Database.database().reference().child("users")....

и вместо этого связал все необходимое для запроса с самим объектом базы данных, и все работало нормально.

Database.database().reference().child("users")
    .queryOrdered(byChild: "username")
    .queryStarting(atValue: searchText)
    .queryEnding(atValue: searchText + "\u{f8ff}")
    .observeSingleEvent(of: .value, with: { ...

Появились только 2 результата: кошка и корова. Очень странная ошибка

let searchText = "c"

Database.database().reference().child("users")
    .queryOrdered(byChild: "username")
    .queryStarting(atValue: searchText)
    .queryEnding(atValue: searchText + "\u{f8ff}")
    .observeSingleEvent(of: .value, with: { (snapshot) in

    if !snapshot.exists() { return }

    // dictionaries plural
    guard let dictionaries = snapshot.value as? [String: Any] else { return }

    dictionaries.forEach({ (key, value) in

        guard let dict = value as? [String: Any] else { return }
        let user = User(dict: dict)

        let isContained = self.users.contains(where: { (containedUser) -> Bool in
            return user.uid == containedUser.uid
        })

        if !isContained {
            self.users.append(user)
            self.collectionView.reloadData()
        }
})
0 голосов
/ 08 апреля 2019

Я только что попробовал этот код:

let ref = Database.database().reference(withPath: "55574954")
ref.child("users") .queryOrdered(byChild: "username") .queryStarting(atValue: "c") .queryEnding(atValue: "d").observeSingleEvent(of: .value, with: { (snapshot) in
    for child in (snapshot.children.allObjects as! [DataSnapshot]) {
        print(child.key)
    }
})

В этой структуре данных:

{
  "users" : {
    "1000" : {
      "userId" : "1000",
      "username" : "bull"
    },
    "2000" : {
      "userId" : "2000",
      "username" : "cat"
    },
    "3000" : {
      "userId" : "3000",
      "username" : "cow"
    }
  }
}

Live JSON - это здесь .

Запуск этого кода печатает:

2000

3000

Это именно то, что я ожидал бы от структуры данных выше.

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