Swift: поиск определенного значения в базе данных Firebase и поиск всех связанных данных - PullRequest
0 голосов
/ 14 февраля 2019

enter image description here enter image description here

У меня есть данные, загружаемые в мою базу данных.Я пытаюсь реализовать функцию поиска, которая позволяет искать что-то по имени, и, если имя найдено, автоматически заполняет текстовые поля данными, соответствующими этому имени.Так, например, если я ищу 'Pepsi Max', я хочу найти pepsi max в моей базе данных, а затем отображать цену / местоположение / рейтинг и т. Д.

У меня в настоящее время есть функция поиска, но она просто просматривает всю базу данных ипечатает все значения

func searchT() {

    let pub = pubName.text

    print(pub)


    let databaseRef = Database.database().reference().child("Drinks")
    let query = databaseRef.queryOrdered(byChild: "pub").queryStarting(atValue: pub).queryEnding(atValue: "\(String(describing: pub))\\uf8ff")

    query.observeSingleEvent(of: .value) { (snapshot) in
        guard snapshot.exists() != false else { return }
        print(snapshot.value as Any)
        DispatchQueue.main.async {

            guard let dict = snapshot.value as? [String:Any] else {
                print(snapshot)
                return
            }

            let pubName = dict["pub"] as? String
            let pubLocation = dict["location"] as? String
            let price = dict["price"] as? String
            let rating = dict["rating"] as? String
            let comment = dict["comment"] as? String

            self.pubName.text?.append(pubName!)
            self.pubLocation.text?.append(pubLocation!)
            self.price.text?.append(price!)
            self.rating.text?.append(rating!)
            self.comment.text?.append(comment!)

        }
    }
}

Вы заметите, что в этой функции я ищу по данным «pubName» (которые, я думаю, я неправильно задаю в первой строке, но не уверен, как это исправить).Эта функция дает сбой в первой строке установки значения для textViews, поскольку 'nil при развертывании необязательного значения' равен 'nil'

Как выполнить поиск по pubName, найти соответствующее значение и затем установить текстовые поля в качестве оставшихся данныхв БД, относящихся к искомому значению.

Заранее спасибо, E

1 Ответ

0 голосов
/ 15 февраля 2019

1.База данных в реальном времени

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

Снимок экрана моей базы данных в реальном времени дляэтот ответ

{
  "Drinks" : {
    "-LYiUHm4vtrB3LqCBxEc" : {
      "location" : "toronto",
      "name" : "pepsi max",
      "price" : 13.5,
      "rating" : 3.6
    },
    "-LYiUHm5Lgt3-LENTdBZ" : {
      "location" : "new york",
      "name" : "diet coke",
      "price" : 15.45,
      "rating" : 5
    },
    "-LYiUHm5Lgt3-LENTdB_" : {
      "location" : "chicago",
      "name" : "mountain dew",
      "price" : 2,
      "rating" : 2
    },
    "-LYiUHm5Lgt3-LENTdBa" : {
      "location" : "vancouver",
      "name" : "sprite",
      "price" : 6.98,
      "rating" : 4.5
    }
  }
}

2.Swift 4.0

Теперь, чтобы найти любой напиток по имени, используйте следующий код:

func search(drinkName: String) {
        let databaseRef = Database.database().reference().child("Drinks")
        let query = databaseRef.queryOrdered(byChild: "name").queryStarting(atValue: drinkName).queryEnding(atValue: "\(drinkName)\\uf8ff")

        query.observeSingleEvent(of: .value) { (snapshot) in
            guard snapshot.exists() != false else { return }
            //print(snapshot.value)
            DispatchQueue.main.async {
                // Update TextFields here
            }
        }
}

Символ \ uf8ff, использованный в запросе выше, является очень высокой кодовой точкойв диапазоне Юникод.Поскольку в Юникоде он указан после большинства обычных символов, запрос соответствует всем значениям, начинающимся с буквы b.

Источник: https://firebase.google.com/docs/database/rest/retrieve-data

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

3.Добавьте «.indexOn» к правилам базы данных в реальном времени

Чтобы вышеуказанный запрос работал и достигал более высокой производительности, вам нужно установить индекс в поле, по которому вы будете искать.Это можно сделать, перейдя на вкладку «Правила» и добавив индекс, как показано ниже:

{
  "rules": {
    ".read": true,
    ".write": true,
      "Drinks": {
        ".indexOn": "name"
      }
  }
}

Источник: Дополнительная информация об индексировании данных

Обновленный ответ для вашегообновленный вопрос:

func searchT() {
        // You must cast pub variable as String.
        guard let pub: String = pubName.text else { return }

        print(pub)


        let databaseRef = Database.database().reference().child("Drinks")

        let query = databaseRef.queryOrdered(byChild: "pub").queryStarting(atValue: pub).queryEnding(atValue: "\(String(describing: pub))\\uf8ff")

        query.observeSingleEvent(of: .value) { (snapshot) in
            guard snapshot.exists() != false else {
                print("failing here")
                return }
            print(snapshot.value as Any)
            DispatchQueue.main.async {

                guard let dict = snapshot.value as? [String:Any] else {
                    print(snapshot)
                    return
                }

                let pubName = dict["pub"] as? String
                let pubLocation = dict["location"] as? String
                let price = dict["price"] as? String
                let rating = dict["rating"] as? String
                let comment = dict["comment"] as? String
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...