Eduard
Eduard

Reputation: 3576

Firestore allow list if a specific field is provided

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

Answers (1)

Doug Stevenson
Doug Stevenson

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

Related Questions