I've been working on a chat app in order to get used to Cloud Firestore.
Below is the structure of its database.
rooms
├ xxxxxx
│ ├ messages
│ │ ├ xxxxxx
│ │ └ xxxxxx
│ └ private
│ └ allowed - members [xxxxxxxx, xxxxxxxx]
└ xxxxxx
├ messages
│ ├ xxxxxx
│ └ xxxxxx
└ private
└ allowed - members [xxxxxxxx, xxxxxxxx]
The private
subcollection under each chat room document has a single document with allowed
as its ID.
allowed
has members
, which is an array field holding IDs of users allowed to use the chat room.
What I have to do first to fetch a particular chat room is to get the allowed
document, as follows:
db.collectionGroup('private')
.where('members', 'array-contains', userId)
.get()
.then(...)
I've already created an index on private
for collection group queries, so the above code works.
However, if I add the following security rule, it fails with the error message of 'Uncaught (in promise) FirebaseError: Missing or insufficient permissions.'
match /{path=**}/private/{document} {
allow read: if request.auth.uid
in get(/databases/$(database)/documents/$(path)/private/$(document)).data.members;
}
This rule is for forbidding a user from accessing allowed
if not a member of the room.
A query without .where(...)
results in the same error.
On the other hand, the rule below works as expected.
match /{path=**}/private/{document} {
allow read: if request.auth.uid in resource.data.members;
}
I know this rule is by far better, so I'll definitely use it, but I still wonder why the previous rule didn't work.
Would anyone clarify the cause please?
Is this possibly related in any way?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…