Below is my firestore database
The message subcollection look like this:
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!
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}