Swift - Firebase search in database

有些话、适合烂在心里 提交于 2019-12-29 14:56:07

问题


I search for users while typing. However at the end it returns every users. I don't know why exactly this happens. It seems alright

 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:


You are using queryStartingAtValue. From the documentation:

The FIRDatabaseQuery instance returned by queryStartingAtValue:childKey will respond to events at nodes with a value greater than startValue, or equal to startValue and with a key greater than or equal to childKey.

So keep in mind that if you search for the name of an user it will give all the users that have name greater in alphabetic order than the given one. You need to set a queryEndingAtValue to limit the query range.

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

Firebase legacy documentation is such a good resource to understand on how firebase handle queries. There you will find:

The f8ff character used in the query above is a very high code point in the Unicode range. Because it is after most regular characters in Unicode, the query matches all values that start with a b.

You might also get interested in Elasticsearch. Flashlight is a node service that integrates elasticsearch and firebase.


Update:

As pointed out in the comments this won't work if the string you are searching for has upper case characters. The solution in this case is to have an additional field in the object with the info you are searching all in lower case. So if you have Satoshi Nakamoto as name you would save an additional nameSearch property with satoshi nakamoto.

And finally make sure your searching string is in lower case too.


There is a few other problems with your code.

  • You are setting an observer. It will trigger the callback anytime your data changes so you should be resetting the users array inside the callback so you don't have duplicated and dirty data.

  • Your function won't return the users with the data since firebase call is async. When you call return users you won't have the users array populated. I recommend you using self.users = users instead of returning it in the function. Otherwise, if you want to proceed with the current approach and return it, you should set a 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
    })
}


来源:https://stackoverflow.com/questions/38274568/swift-firebase-search-in-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!