Swift:在Firebase数据库中搜索特定值&;查找所有相关数据
我有数据上传到我的数据库。我正在尝试实现搜索功能,我可以通过名称搜索某些内容,如果找到名称,则自动填充包含该名称对应数据的文本字段。例如,如果我搜索“Pepsi Max”,我想在我的数据库中找到Pepsi Max,然后显示价格/位置/评级等 我目前有一个搜索功能,但它只搜索整个数据库并打印所有值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
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设置为数据库中与搜索值相关的剩余数据
提前感谢,E1。实时数据库 由于您没有包括数据库的结构,我假设您有一个饮料的数据库结构,如下所示:
{
"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