I have a database scheme that is essentially the same that the one is the documentation :
// An index to track Ada's memberships
{
"users": {
"alovelace": {
"name": "Ada Lovelace",
// Index Ada's groups in her profile
"groups": {
// the value here doesn't matter, just that the key exists
"techpioneers": true,
"womentechmakers": true
}
},
...
},
"groups": {
"techpioneers": {
"name": "Historical Tech Pioneers",
"members": {
"alovelace": true,
"ghopper": true,
"eclarke": true
}
},
...
}
}
I would like to create a DatabaseQuery
that gets all users that take part of a specific group (for instance users whose "groups" contain "techpionneers")
How should I proceed ? I tried a Database.database().reference(withPath: "users").queryOrdered(byChild: "groups").queryEqual(toValue: "techpioneers")
but that does not work (obviously).
Franks solution is spot on but an alternative is to use a Deep Query i.e. ordering by deep paths to query the users node for child->child nodes that match the criteria. Here's the format
let ref = self.ref.child("users")
let query = ref.queryOrdered(byChild: "groups/techpioneers").queryEqual(toValue: true)
query.observeSingleEvent(of: .value, with: { (snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
print(snap)
}
})
the result is all of the users that are part of the techpioneers group
"alovelace": {
"name": "Ada Lovelace",
"groups": {
"techpioneers": true,
"womentechmakers": true
}
}
To load all users that are part of a specific group, start in the /groups
node to find their key:
ref.child("groups/techpioneers/members").observeSingleEvent(of: .value, with: { (snapshot) in
That gives you the keys of all members. Then loop over those keys and load the corresponding user.
This is essentially a client-side join operations. While you may initially think this is incredibly slow, it's actually not all that bad since Firebase pipelines the requests over a single connection. See http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786.