Search code examples
javascriptgoogle-cloud-firestorefirebase-security

Cloud Firestore custom claims with query


I have a firebase collection notes where each document has a user-id array that contains some user ids.

I've set a custom claim on my user access token that is in the format of nid=true (where nid is the note document id they should have access to) however when I try and query the collection for any relevant documents I receive a permission error.

My query is written as follows:

const notesRef = collection(db, "notes");
        const allNotesQuery = query(
          notesRef,
          where("user_ids", "array-contains", user.uid)
        );

        const noteDocs = await getDocs(allNotesQuery);

my security rules are:

match /notes/{nid} {
        allow read, write: if request.auth != null && request.auth.token[(nid)] == true
    }

I've also tried nid without the brackets around it like so, but it still doesn't work

match /notes/{nid} {
        allow read, write: if request.auth != null && request.auth.token[nid] == true
    }

Can anyone see anything obviously wrong with this? If I inspect my token I see the custom claim set correctly with the correct nid value. Unfortunately I can't find a way to test custom claims in the developer console.

*** edit ***

As a follow up to my comments on the first posted answer. The following doesn't work.


allow read, write, list: if  request.auth != null && request.auth.token[nid] in resource.data.user_ids

but this does:

allow read, write, list: if  request.auth != null && request.auth.uid in resource.data.user_ids

Solution

  • Firestore security rules don't filter the data. Instead they merely ensure that your app is not requesting more data than it's permitted to. For more on this, see the Firebase documentation on rules are not filters.

    Since your code is not in any way filtering on the nid token (as far as I can tell), the rules reject the operation. So modify the query to only request only note IDs that the user has access to, and then the rule you wrote can validate it.