Reputation: 3576
So I've been searching a lot and I can't find anything on the matter. Take a collection of post comments which is readable by logged in users only.
How do I write the security rules for the list operation in order to allow listing only when trying to fetch comments on a specific post. Query is as simple as follows:
let query = store.comments
.where( 'postId', '==', postId )
.orderBy( 'createdAt', 'desc' )
.limit(10)
.get()
I'm worried about people simply fetching comments with no specific postId in mind. So I've limited the amount of queried documents to max. 10 per request, as well as needing to be logged in when doing so, but, for trying to allow listing only when postId is present, I have tried so many variants of which none worked.
match /comments/{key} {
allow list: if isLoggedIn() && request.query.limit <= 10 && request.resource.data.keys().hasAny(['postId'])
}
Doesn't work.
allow list: if isLoggedIn() && request.query.limit <= 10 && request.resource.data.postId is string
Also not working.
allow list: if isLoggedIn() && request.query.limit <= 10 && request.resource.data.postId == resouce.data.postId
Still nothing. Tried with hasAll and hasOnly, still no. What I think happens is that request.resource.data doesn't actually exist when simply listing documents.
I know you can check the query.orderBy, but that doesn't help in my case.
Please advise
Upvotes: 0
Views: 229
Reputation: 317437
What you're doing with request.resource.data.keys().hasAny(['postId'])
is currently not supported. Note that the API document says of request.resource:
The new resource value, present on write requests only.
Security rules don't provide access to the data into the query filters. That is to say, there is no expression that can require a certain named filter is present in order to execute the query. (Though you can, of course, check that the value of a filter is valid by comparing the existing document field values to known strings or variables.)
As you suggested in your comment, you should organize the data using postId as the document ID of the collection. That would force the client to know a postId of a document, as long as you disallow list
access on that collection (which would deny all queries that are not just document gets).
Upvotes: 1