我在打字时搜索用户。但最终它会返回每个用户。 我不知道为什么会发生这种情况。好像很好
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
}
答案 0 :(得分:19)
您正在使用queryStartingAtValue
。来自documentation:
返回的
FIRDatabaseQuery
实例queryStartingAtValue:childKey
将使用a响应节点上的事件 值大于startValue,或等于startValue和键 大于或等于childKey。
所以请记住,如果您搜索用户的name
,它将为所有用户提供字母顺序比给定名称更大的用户。您需要设置queryEndingAtValue
以限制查询范围。
ref.child("Users").queryOrderedByChild("name").queryStartingAtValue(text).queryEndingAtValue(text+"\u{f8ff}")
Firebase legacy documentation是了解firebase如何处理查询的一个很好的资源。你会在那里找到:
上面查询中使用的f8ff字符是一个非常高的代码点 在Unicode范围内。因为它是在大多数常规字符之后 Unicode,查询匹配以b开头的所有值。
您可能也对Elasticsearch感兴趣。 Flashlight是一个集成了elasticsearch和firebase的节点服务。
正如评论中所指出的,如果您要搜索的字符串具有大写字符,则将无法正常工作。在这种情况下,解决方案是在对象中有一个附加字段,其中您正在搜索的信息全部为小写。因此,如果Satoshi Nakamoto
为name
,则可以使用nameSearch
保存其他satoshi nakamoto
属性。
最后确保你的搜索字符串也是小写的。
您的代码还存在其他一些问题。
您正在设置观察者。它会在您的数据发生变化时触发回调,因此您应该重置回调中的users
数组,这样您就不会有重复数据和脏数据。
由于firebase调用是异步的,因此您的函数不会返回带有数据的用户。当您致电return users
时,您将无法填充用户数组。我建议您使用self.users = users
而不是在函数中返回它。否则,如果您要继续使用当前方法并将其返回,则应设置completion handler。
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
})
}