Search code examples
firebasefluttergoogle-cloud-firestorefirebase-security

Firebase Security Rules with wildcards (Permission denied even though access is granted)


Below is my firestore database

enter image description here

The message subcollection look like this:

enter image description here

Below is my security rules.

match /channels/{channelID=**} {
    allow read: if request.auth.uid in resource.data.participants;
    allow write: if request.auth.uid in resource.data.participants;

However, when I try to listen to the message documents in the message collection with the code below

firestore.collection('channels').doc(channelId).collection('messages').snapshots()

I received the following error:

flutter: [cloud_firestore/permission-denied] The caller does not have permission to execute the specified operation.

8.3.0 - [Firebase/Firestore][I-FST000001] Listen for query at channels/RILvs2HvV8OiYrsk0W0ZxhxaU8H3-EpPAVCmuYnTWGxvASNk5rgUHTe63/messages failed: Missing or insufficient permissions.

I have allowed access to all the subcollections and documents with =** in the security rules, but I'm not sure why is permission still denied? Any advice would be appreciated. Thanks!


Solution

  • The problem is in you are trying to read documents in messages sub-collection and so resource.data will be data of those messages documents and not the channel document. The participants array however is present in the channel document so yry using get() instead to read that document's data as shown below.

    match /channels/{channelId}/messages/{messageId} {
        allow read, write: if request.auth.uid in get(/databases/$(database)/documents/channels/$(channelId)).data.participants;
    }
    

    If you use recursive wildcard here then value of channelId would be "/RILvs2HvV8OiYrsk0W0ZxhxaU8H3-EpPAVCmuYnTWGxvASNk5rgUHTe63/messages/JR12q13OvpYISJmHilcq" (in this example) but the path in get() should be just /channels/{channelId}