I am having troubles writing Firestore rules to securely allow fetching a document by its ID and an additional field. Let's consider that I want to fetch the user with the ID USER_ID only if his deletionDate is null.
I wrote the following security rule:
/users/{userId} {
allow read: if resource.data.deletionDate == null;
}
My query with the JS client:
await db.collection('users')
.where(firebase.firestore.FieldPath.documentId(), '==', 'USER_ID')
.where('deletionDate', '==', null)
.limit(1)
.get();
It appears that this is not handled as a query on a collection. But rather like a document fetched by its ID. The Firestore simulator throws the following exception for non existing docs:
Variable read error. Variable: [resource]. for 'list'
Changing the security rule to resource == null || resource.data.deletionDate == null does not help. The thing is, I would prefer to receive an empty result if the document cannot be fetched because of absent / with deletionDate. I don't want mute the permission exception received by the clients. So I can monitor potential misconfigurations.
I noticed that the following query does exactly what I want:
await db.collection('users')
.where(firebase.firestore.FieldPath.documentId(), '!=', 'FAKE_ID')
.where(firebase.firestore.FieldPath.documentId(), '==', 'USER_ID')
.where('deletionDate', '==', null)
.limit(1)
.get();
But this looks too hacky to be used in production. Thanks for your help!