I have a collection named "dms" that has "firstUserId" and "secondUserId" as fields in its documents. The following rule is giving me permission denied error:
match /dms/{dmsId=**} {
allow read, update, delete:
if request.auth.uid == resource.data.firstUserId ||
request.auth.uid == resource.data.secondUserId;
allow create:
if request.auth.uid == request.resource.data.firstUserId ||
request.auth.uid == request.resource.data.secondUserId;
}
however, if I hardcode the value of firstUserId (e.g. request.auth.uid == "hard_coded_userId"
) it works.
So resource.data.whateverfieldname must not be returning the correct data. there are no typos in my field names and no extra whitespaces.
Flutter source code snippet:
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('dms')
.doc(userMessages[index])
.collection('messages')
.orderBy(
'createdAt',
descending: true,
)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
Your query can never work.
messages
subcollection, but your rules depend on data that is only present in the dms
document(s). The rules engine will not read that parent document, so resource.data.firstUserId
and resource.data.secondUserId
will never have any value.So as Tom commented, if you want the rules to work as they are now, you'll have to duplicate the firstUserId
and secondUserId
values into each messages
document too.
Alternatively you might be able to get the parent document in rules specific to the subcollection and check those values. Note the might there, as I didn't check if this actually works.
Also see: