Let's say I have a structure like this:
-users
  -user1_uid
    name
    distance
    age
How would I do a query like (Find users with distance <100 and age between 20 and 25)?
I have tried the standard method
        let recentPostsQuery = (ref?.child("users").queryOrderedByChild("age").queryStartingAtValue("20"))!
M problem is, that is does not appear to be possible to query multiple childs (like combining age and distance filtering). Did something change in this regard compared to Firebase a few months ago? Filtering them locally after the first query is not an option, I believe, as there could be potentially thousands of objects.
A Firebase reference represents a particular location in your Database and can be used for reading or writing data to that Database location. The Query class (and its subclass, DatabaseReference ) are used for reading data. Listeners are attached, and they will be triggered when the corresponding data changes.
If your data model needs something more than a single join query, never choose firebase. It is highly suggested not to choose Firebase for android application if your intended operation is to perform deep and complex querying.
Firebase uses NoSQL; MySQL uses SQL.
My first choice would be to query for all the users between 20 and 25 and then filter in code for ones with a distance < 100.
The question states filtering in code is not an option but I wanted to include it for completeness for situations where it was several thousand nodes or less:
    struct User { //starting with a structure to hold user data
        var firebaseKey : String?
        var theAge: Int?
        var theDistance: Int?
    }
    var userArray = [User]() //the array of user structures
    usersRef.queryOrderedByChild("age").queryStartingAtValue(20)
     .queryEndingAtValue(25).observeEventType(.Value, withBlock: { snapshot in
        for child in snapshot.children { //.Value so iterate over nodes
            let age = child.value["age"] as! Int
            let distance = child.value["distance"] as! Int
            let fbKey = child.key!
            let u = User(firebaseKey: fbKey, theAge: age, theDistance: distance)
            userArray.append(u) //add the user struct to the array
        }
        //the array to contain the filtered users
        var filteredArray: [User] = []
        filteredArray = userArray.filter({$0.theDistance < 100}) //Filter it, baby!
        //print out the resulting users as a test.
        for aUser in filteredArray {
            let k = aUser.firebaseKey
            let a = aUser.theAge
            let d = aUser.theDistance
            print("array: \(k!)  \(a!)  \(d!)")
        }
    })
}
Now a potential super simple answer.
    let usersRef = self.myRootRef.childByAppendingPath("users")
    usersRef.queryOrderedByChild("age").queryStartingAtValue(20)
     .queryEndingAtValue(25).observeEventType(.ChildAdded, withBlock: { snapshot in
        let distance = snapshot.value["distance"] as! Int
        if distance < 100 {
            let age = snapshot.value["age"] as! Int
            let fbKey = snapshot.key!
            print("array: \(fbKey)  \(age)  \(distance)")
        }
    })
Notice that we are leveraging .ChildAdded instead of .Value so each node is read in one at a time - if the distance is not what we want, we can ignore it and move on to the next.
Firebase can't combine always the conditions. How to query based on multiple conditions in Firebase?
But, using the new firebase API, this post can give some hints: Query based on multiple where clauses in firebase
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With