2
function isWriter(request,resource) {
  return ('writerIds' in resource.data) && resource.data.writerIds == request.auth.uid;
}

 match /bookmarks/{bookmarks} {
    allow read: if  isWriter(request,resource)
}

In my bookmark collection, When I put the accessible writer's id into writerIds key then this rules fails but if i change the key to studentId and change the rule into below mentioned way, then it works

   function isWriter(request,resource) {
  return ('studentId' in resource.data) && resource.data.studentId == request.auth.uid;
}

 match /bookmarks/{bookmarks} {
    allow read: if isWriter(request,resource)
}

The only differnece between both the keys is that studentId is a composite index but writerIds is not.

My Document looks like

{isBookmark:boolean, studentId:string, writerIds:string}

I have also tried with the partial conditions as well by changing the isWriter Function to this for both studentId and writerIds but this behaves same as above.

function isWriter(request,resource) {return ('writerIds' in resource.data)}

Is it possible that resource object only access the keys which are composite index?

  • I don't believe a composite index has anything to do with security rules. How are you setting the values for the `writerIds` and `studentId` fields so you can compare them to `request.auth.uid`? Can you also show the contents of the document and the queries that you're using or how you are testing the rules? – Álvaro Zamora Jun 02 '21 at 14:59
  • @ÁlvaroZamora I am testing it by setting values manually like i kept same values in both the fields but one passed and one didn't. I don't think this is something related to value/content mismatch because if that is the case then at least "function isWriter(request,resource) {return ('writerIds' in resource.data)} " this condition should have passed. – Piyush Agarwal Jun 03 '21 at 00:32

1 Answers1

0

According to the security rules documentation:

"[...] when Cloud Firestore applies your security rules, it evaluates the query against its potential result set, not against the actual properties of documents in your database. If a query could potentially include documents that violate your security rules, the query will fail."

So, in your case, the issue is likely in the query you're executing. I replicated your document and ran some tests:

This would NOT work with your security rule:

db.collection('/bookmarks')
        .get()

However this would work:

db.collection('/bookmarks')
        .where("writerIds", ">=", "")
        .get()

I also found another post with a similar issue if you want to see another example.