1
votes

In my Firestore, I am working with subcollections within subcollections to form a large 'tree-like' data structure. Each user will be a single point in this tree, whether he is the root (start), a leaf (somewhere at end), or somewhere in the middle.

The entire tree is around 20 layers deep and I simply used recursion to grab all the data from my front-end. The problem I am having is grabbing all the information UNDER a specific user without being able to read any user considered above in regards to the Firestore security rules. For example, the root user (at start) has NOBODY besides himself able to read that document and leaf users (at end) has EVERYBODY able to read that user document.

Is there anyway I can specify in my firestore security rules so I am able to get all documents/subcollections under a user document? Something along the lines of:

match /users/{userDocument=**} {
        allow read, write: if resource.data.userid == request.auth.uid;
        // Not actual code but something like this where now under my user document, i can read all other users under me in tree
        if resource.data.userid == request.auth.uid {
                match /{furtherDepthUserDocuments=**} {
                        allow read: if true;
                }
        }
}

This is where I locate my own user document and now can read from all users under me using a wildcard.

Edit: Example.) One such example could be a school-like system with the following:

teachers/
         {teachDocid1}/
                       undergrads/
                                {undergradDocid1}/
                                                  phdAssignments/
                                                                 {docid}..
                       tutors/
                                {tutorsDocid1}/
                                                 tutorAssignments/
                                                                 {docid}..
         {teachDocid2}/
                       graduates/
                                {graduatesDocid1}/
                                                 classHomeworks/
                                                                 {docid}..
         {teachDocid3}/
                       preschoolers/
                                 {preschoolersDocid1}/
                                                 studentProjects/
                                                                 {docid}.     

I apologize if this seems overly complex, but if a teacher logs in (ex. if that teacher corresponds to {teachDocid1}), they would be able to view their undegrads, phdAssignments, tutors, and tutorAssignments. Now if an undergrad under root {teachDocid1} logs in, they would be able to view only phdAssignments.

Each doc in this tree has a userid field that references the user this document associates too as well. I can easily find the corresponding document/path with a usersid, but is there any recursive ways to then allow a read in security for everything under this specified document?

Also would there be a specific way to query for these documents in Node.js?

1
It's not really clear to me what you're trying to do. It might help if you show example data along with specific queries for that data that should either pass or fail the rules you want.Doug Stevenson
Please, provide examples of how you are doing. Due to the fact that the Security Rules are not the best way to filter data, we need further details and information on how you are trying to do and what you are expecting, to better assist you.gso_gabriel
I added the example, I apologize for not adding one previously. But you can see how each user will be a different undefined depth, and then they should be able to read all users under that depth.Jeff

1 Answers

0
votes

Structure your collection using the uid as document id and filter, try this for instance:

match /users/{userDocument=**} {
  allow read, write: if resource.data.userid == request.auth.uid;
  match /uid/{document=**} {
    allow read: if request.auth.uid == uid;
  }
}

This is untested