skip to Main Content

I have a simple Firestore rule for a collection:

match /mycollection/{documents=**} {
  allow read, write: if request.auth != null && request.auth.uid == resource.data.author
  allow create: if request.auth != null && request.auth.uid == request.resource.data.author
}

Basically to access mycollection, author must be equal to uid. This is working fine, where I can query this collection via react using:

import { collection, where, query, orderBy } from 'firebase/firestore';
import { useCollection } from 'react-firebase-hooks/firestore';

...
const [col, loading, error] = useCollection(
  query(collection(db, "mycollection"), where("author", "==", uid), orderBy("createdAt", "desc"))
)
...

Now I want to access a sub-collection but cannot do it:

const [collection, loading, error] = useCollection(
  query(collection(db, `mycollection/${id}/subcollection`), orderBy("createdAt", "desc"))
)

I get the FirebaseError: Missing or insufficient permissions. error. Looks like I can’t get to the subcollection without authenticating the parent collection, which is fine. But how do I pass the where condition to parent collection in the above query?

2

Answers


  1. Chosen as BEST ANSWER

    Thanks @alex-mamo for the direction. However I might have found a solution that works better for me.

    match /mycollection/{colId} {
      allow read, write: if request.auth != null && request.auth.uid == resource.data.author
      allow create: if request.auth != null && request.auth.uid == request.resource.data.author
      
      match /subcollection/{subColId} {
        allow read, write, create: if request.auth != null && request.auth.uid == get(/databases/$(database)/documents/mycollection/$(colId)).data.author
      }
    }
    

    This rule gets author value from the parent document and compares it with current user's uid. If they are equal, the user has access to the sub-collection.


  2. The rules for the top-level collections do not apply to sub-collections. You have to explicitly define rules for your sub-collections. So to solve this, you can nest the sub-collections rules in the collection itself. So your rules should look like this:

    match /mycollection/{documents=**} {
      allow read, write: if request.auth != null && request.auth.uid == resource.data.author
      allow create: if request.auth != null && request.auth.uid == request.resource.data.author
    
        match /subcollection/ {
          //Your rules
        }
    }
    

    Please also see below, a link that explains how to use hierarchical data:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search