我在打字时搜索用户。但是,最后它会返回每个用户。我不知道为什么会发生这种情况。似乎没问题
class func findUsers(text: String)->[User]{
let user = User()
var users = [User]()
ref.child("Users").queryOrderedByChild("name").queryStartingAtValue(text).observeEventType(.Value, withBlock: { snapshot in
for u in snapshot.children{
user.name = u.value!["name"] as? String
user.surname = u.value!["surname"] as? String
user.email = u.value!["email"] as? String
user.score = u.value!["score"] as? Int
user.status = u.value!["status"] as? Int
user.id = u.value!["id"] as? String
user.pin = u.value!["pin"] as? String
users.append(user)
print(user.name)
}
})
print("users:", users)
return users
}
您正在使用queryStartingAtValue
.从文档中:
返回的
FIRDatabaseQuery
实例queryStartingAtValue:childKey
将使用 值大于 startValue,或等于 startValue 且带有键 大于或等于子密钥。
因此请记住,如果您搜索用户的name
,它将为所有按字母顺序排列名称大于给定名称的用户。您需要设置一个queryEndingAtValue
来限制查询范围。
ref.child("Users").queryOrderedByChild("name").queryStartingAtValue(text).queryEndingAtValue(text+"u{f8ff}")
Firebase 旧版文档是了解 Firebase 如何处理查询的好资源。在那里你会发现:
上述查询中使用的 f8ff 字符是一个非常高的代码点 在 Unicode 范围内。因为它在大多数常规字符之后 Unicode,查询匹配以 b 开头的所有值。
您可能还会对 Elasticsearch 感兴趣。Flashlight是一个集成了弹性搜索和Firebase的节点服务。
更新:
如注释中所述,如果您要搜索的字符串具有大写字符,这将不起作用。在这种情况下,解决方案是在对象中有一个附加字段,其中包含您正在搜索的信息全部以小写形式出现。因此,如果您有Satoshi Nakamoto
name
,您将使用 satoshi nakamoto
保存额外的nameSearch
属性。
最后,确保您的搜索字符串也为小写。
您的代码还有其他一些问题。
您正在设置观察者。每当数据更改时,它都会触发回调,因此您应该在回调中重置
users
数组,这样您就不会有重复和脏数据。您的函数不会向用户返回数据,因为 Firebase 调用是异步的。调用
return users
时,不会填充用户数组。我建议您使用self.users = users
而不是在函数中返回它。否则,如果要继续使用当前方法并返回它,则应设置完成处理程序。
class func findUsers(text: String)->Void{
ref.child("Users").queryOrderedByChild("name").queryStartingAtValue(text).queryEndingAtValue(text+"u{f8ff}").observeEventType(.Value, withBlock: { snapshot in
var user = User()
var users = [User]()
for u in snapshot.children{
user.name = u.value!["name"] as? String
...
users.append(user)
}
self.users = users
})
}