I'd like to add a Firestore security rule that allows a collection group query, but only if there's a where clause on the id
field. In essence, I'm like to allow the user to retrieve the document only if s/he knows the id
.
In other words, I'd like to allow this:
db.collectionGroup('widgets').where('id', '==', '123').get()
...but not this:
db.collectionGroup('widgets').get()
The security rule would look something like this:
match /{path=**}/widgets/{widgetId} {
allow list: if request.query.keys().hasAny(['id']);
}
Is there a way to do this?
There is no way to check the properties of the query filters. All you have access to in the query is what you see in the documentation for request.query. Rules that limit access to documents based on their contents are always expressed in terms of the documents that would be matched by the query.
You could restrict queries to one particular known id:
allow list: if request.resource.data.id == '123';
or a set of IDs, or an ID from another source (such as custom claims, or another document).
But if you want someone to only get a document using known "private" information that's specified in the query, that information will have to be in the document ID itself, not a field:
allow get; // anyone can get a single document by ID, if they know that ID
// but do not allow read or list
This might require a change to your data model, or maybe a copy of data indexed by this other ID that you want to allow.