一尘不染

Swift-数据库中的Firebase搜索

swift

我在输入时搜索用户。但是最后它返回了每个用户。我不知道为什么会这样。好像还好

 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
}

阅读 293

收藏
2020-07-07

共1个答案

一尘不染

您正在使用queryStartingAtValue。从文档中

FIRDatabaseQuery返回的实例
queryStartingAtValue:childKey将响应节点上具有大于startValue或等于startValue且键大于或等于childKey的值的事件。

因此请记住,如果您搜索name某个用户的,则会为所有名称按字母顺序大于给定名称的用户提供。您需要设置a
queryEndingAtValue以限制查询范围。

ref.child("Users").queryOrderedByChild("name").queryStartingAtValue(text).queryEndingAtValue(text+"\u{f8ff}")

Firebase旧版文档是了解Firebase如何处理查询的好资源。在那里您会发现:

上面查询中使用的f8ff字符在Unicode范围内是一个很高的代码点。因为它在Unicode中大多数常规字符之后,所以该查询匹配所有以b开头的值。

您可能还会对Elasticsearch感兴趣。Flashlight是一个将Elasticsearch和Firebase集成在一起的节点服务。


更新:

如注释所指出的, 如果您搜索的字符串有大写字符,将无效 。在这种情况下,解决方案是 在对象中 有一个
附加字段,其中要搜索的信息全部用小写字母表示 。因此,如果有的话Satoshi Nakamotoname您可以使用保存其他nameSearch属性satoshi nakamoto

最后确保您的搜索字符串也使用小写字母。


您的代码还有其他一些问题。

  • 您正在设置观察者。每当您的数据更改时,它都会触发回调,因此您应该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
    })
}
2020-07-07