Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase querying

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.

like image 576
Nico Reese Avatar asked May 20 '16 09:05

Nico Reese


People also ask

What is a Firebase query?

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.

Is Firebase good for queries?

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.

Which query language is used in Firebase?

Firebase uses NoSQL; MySQL uses SQL.


2 Answers

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.

like image 177
Jay Avatar answered Oct 01 '22 05:10

Jay


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

like image 41
Alexis Clarembeau Avatar answered Oct 01 '22 07:10

Alexis Clarembeau