For example, I want to get all users who is member of some "space".
Simplified Firestore rule example:
match /users/{userId} {
allow read: if exists(/databases/$(database)/documents/spaces/SPACEID/members/$(userId));
}
JS code in Web site:
firebaseApp
.firestore()
.collection("users")
.where( ??? )
.onSnapshot((querySnapshot) => {
...
});
I was able to come up with only 2 working options:
- Create
spacesArrayfield in/userscollection and useusersRef.where("spacesArray", "array-contains", "SPACEID"). But in this case anyone can find out what groups the user is in by readingspacesArray. Also, the problem is that these arrays can be quite large, while this data is not needed on the client side, this causes excessive traffic. - Get all members list in space first
/databases/$(database)/documents/spaces/SPACEID/members/and gets every user one by one. The problem with this option is that there can be a lot of users, every time the page is refreshed, hundreds or thousands of users will be requested via.get()or.onSnapshot(), which is redundant.
The ideal option would be to use an analogue of the exists(...) method from the rules in the where field, or somehow filter out spacesArray from the user's document for confidentiality purposes.