Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift:在Firebase数据库中搜索特定值&;查找所有相关数据_Swift_Firebase_Firebase Realtime Database - Fatal编程技术网

Swift:在Firebase数据库中搜索特定值&;查找所有相关数据

Swift:在Firebase数据库中搜索特定值&;查找所有相关数据,swift,firebase,firebase-realtime-database,Swift,Firebase,Firebase Realtime Database,我有数据上传到我的数据库。我正在尝试实现搜索功能,我可以通过名称搜索某些内容,如果找到名称,则自动填充包含该名称对应数据的文本字段。例如,如果我搜索“Pepsi Max”,我想在我的数据库中找到Pepsi Max,然后显示价格/位置/评级等 我目前有一个搜索功能,但它只搜索整个数据库并打印所有值 func searchT() { let pub = pubName.text print(pub) let databaseRef = Database.databas

我有数据上传到我的数据库。我正在尝试实现搜索功能,我可以通过名称搜索某些内容,如果找到名称,则自动填充包含该名称对应数据的文本字段。例如,如果我搜索“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”进行搜索(我认为第一行中的设置不正确,但不确定如何更正)。此函数在将TextView设置为值的第一行崩溃,因为在展开可选值时存在“nil”

如何按pubName搜索,找到相应的值,然后将textfields设置为数据库中与搜索值相关的剩余数据


提前感谢,E

1。实时数据库

由于您没有包括数据库的结构,我假设您有一个饮料的数据库结构,如下所示:

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

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字符在Unicode范围内是一个非常高的代码点。因为它位于Unicode中大多数常规字符之后,所以查询匹配所有以b开头的值

资料来源:

注意: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
            }
        }
    }

你好,谢谢你的回复!我已经更新了上面的代码以显示我当前的进度。粘贴的代码仍然打印数据库中的所有值,而不是我要查找的特定值。谢谢大家!@EoghanCasey你介意在你的问题上附上实时数据库和数据库规则的截图吗?更改代码中的这两行:guard let pub:String=pubName.text else{return}&let query=databaseRef.queryOrdered(byChild:“pub”).queryStarting(atValue:pub).queryend(atValue:(pub)\\uf8ff)由于pub变量是可选字符串,因此您的查询必须失败。按上述方式进行更改应该可以解决此问题。另外,请确保您查询的发布名称与数据库上的完全相同,因为此查询区分大小写。请让我知道它有帮助。该函数没有超过“guard snapshot.exists()!=false else{return}”行,因此之后不会发生任何事情,也不会进行打印或其他任何操作。我已经调试过了&可以看出pub变量工作正常,正如预期的那样,因此查询或快照可能有问题。谢谢,E