With you current structure that query requires iterating over the skills array, which is not an operation the Firebase server supports. This is one of the many reasons Firebase recommends against using arrays.
If you change you data structure to:
{
"firstName":"John",
"lastName":"Smith",
"age":25,
"skills":{
"jquery": true,
"c++": true,
"mongo": true,
"firebase": true
},
"address":{
"streetAddress":"21 2nd Street",
"city":"New York",
"state":"NY",
"postalCode":"10021"
}
}
You can write your query as:
ref.child('users').orderByChild('skills/jquery').equalTo(true)
The query is probably what you want, but it requires that you add indexes like this:
"users" {
"$uid": {
".indexOn": ['skills/jquery', 'skills/c++', 'skills/mongo', 'skills/firebase']
}
}
These indexes get out of hand quickly and cannot be added programmatically. This is typically a sign that your data structure is wrong.
The proper data structure for a NoSQL database typically reflects the use-case of your app. You need to find users for a specific skill, in that case you should keep a list of users for each skill.
"uids_per_skill": {
"jquery": {
"uidOfJohnSmith": true,
"uidOfAravchr": true
},
"c++": {
"uidOfJohnSmith": true
},
"mongo": {
"uidOfJohnSmith": true,
"uidOfAravchr": true
},
"firebase": {
"uidOfJohnSmith": true,
"uidOfPuf": true
}
}
Now you can determine the list of users who know jQuery with a simple lookup (instead of a query):
ref.child('uids_per_skill').child('jquery').on('value', function(userKeys) {
userKeys.forEach(function(userKey) {
ref.child('users').child(userKey.key()).once('value', function(userSnapshot) {
console.log(userSnapshot.val());
});
});
});
This type of data modeling is called denormalizing and is covered in the Firebase blog post on the topic, in the Firebase documentation on structuring data and in this great article on NoSQL data modeling.