简体   繁体   中英

Firestore: how to filter documents by existing in other collection?

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:

  1. Create spacesArray field in /users collection and use usersRef.where("spacesArray", "array-contains", "SPACEID") . But in this case anyone can find out what groups the user is in by reading spacesArray . 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.
  2. 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.

Firestore queries can only order/filter on data that is part of the documents the query returns. There is no way to order/filter on information in another document/collection.

So your exists check in the security rules is typically great for getting individual documents (known as get in the more granular security rules syntax), but not for handling bulk reads (known as list in granular security rules).

If you consider the list of spaces for a user private information, consider storing it in a UserSpaces collection, which (as you say in #2) leads to more reads, or consider storing only a one-way hash of the space in the public array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM