Ybrin Ybrin - 5 months ago 38
Swift Question

Firebase complex query clauses

If I have the following structure in Firebase:

{
"images": {
"first_image": {
"url": "https://ima.ge/first_image",
"uploader": "john",
"timestamp": "1465920841"
},
"second_image": {
"url": "https://ima.ge/second_image",
"uploader": "louis",
"timestamp": "1465920987"
},
"third_image": {
"url": "https://ima.ge/third_image",
"uploader": "peter",
"timestamp": "1465920990"
}
},

"votes": {
"first_image": {
"john": "up",
"louis": "down"
"francis": "up"
},
"second_image": {
"john": "up",
"louis": "down"
},
"third_image": {
"francis": "up"
}
}
}


Is it possible to query for example all the images which
john
has not voted for already with Firebase?

I read through the documentation and as I understand it, these kinds of queries are not possible at all. So if this is not possible, how could I try to re-structure my data in order to be able to make queries like that in my given example?

I am using the "new" Firebase console and currently the iOS and Android version of the Firebase SDK but I don't need a specific example, instead I want to understand how it is possible to make complex queries in Firebase, either by re-structuring my data or, if I misunderstood the documentation, through normal queries.

The biggest problem of filtering data on the client side is that there could potentially be millions of images and retrieving all of them would be really bad...

Jay Jay
Answer

Yes, You can do this.

Here's an example to find nodes that do NOT have john voting, which will return the third_image node from the structure in the question.

let ref = self.myRootRef.childByAppendingPath("votes")
ref.queryOrderedByChild("john").queryEqualToValue(nil)
      .observeEventType(.Value, withBlock: { snapshot in
      for child in snapshot.children {
           print(child)
      }
})

Remember .Value returns multiple nodes so we need to iterate over then with for child... to get to each one.

As a side note, if these are Firebase users, you should use the userId instead of the persons name. Disassociate dynamic data (a persons name for example) from it's key whenever possible and refer to the key. John may want to be called Johnny in the future.

Comments