Swift - 数据库中的Firebase搜索

时间:2016-07-08 20:03:49

标签: swift firebase firebase-realtime-database

我在打字时搜索用户。但最终它会返回每个用户。 我不知道为什么会发生这种情况。好像很好

 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
}

1 个答案:

答案 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 Nakamotoname,则可以使用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
    })
}