0

I'm having trouble querying a collection where the documents have differing permissions on them.

Is there anyway to perform a query on a collection to prevent getting permissions denied on documents I can't read. I'm able to achieve this if I query them one at a time.I need to query the collection to return multiple docs where I might not have permissions for some? I could keep a list of document Ids a specific user has access to query, but I can't find any documentation on specifying an array of documents.

Collection:

Library > { libraryID } > {
   Users:{ uid, uid, uid },
   title: 'Title of library'
}

Rules:

match /Library/{libraryID} {
  allow read: if get(/databases/$(database)/documents/Library/$(libraryID)).data.Users[(request.auth.uid)] == true;
}

Permission are limited if the users id is in the data.

This works fine:

this.afs.collection<Library('Library').doc({libraryID}); // Everything works great

But I need multiple items from the collection, so when I try something like the example below if fails as I do not have permissions to all the documents in the collection:

this.afs.collection<Library('Library'); //PERMISSION DENIED

I was hoping I could use query to fix this, but because it is looking into the document it also fails:

this.afs.collection<Library('Library',ref => ref.where('Users/'+this._uid, '==', 'true')); // PERMISSION DENIED

So I wish I could just specify the docs I have access to ( this is what I need ) and return them in a collection

this.afs.collection<Library('Library').doc([{libraryID},{libraryID2},{libraryID3}])

If anyone knows a solution to achieve this, or a refactor of the structure to achieve this it would be a huge help.

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • how exactly is your Users node?. it should be a map. – Hareesh Nov 15 '17 at 18:38
  • The User field in the document is just a object with the uid as the key and value of true. It's just used to keep a list or users associated with the Library User: { 'sdfsdf234234234': true, 'oine345jnw3f': true }. When the rules looks at it, it's just seeing if they exist – user1019416 Nov 15 '17 at 18:58

1 Answers1

0

Try this rule

match /Library/{libraryID} {
  allow read: if exists(/databases/$(database)/documents/Library/$(libraryID)/Users/$(request.auth.uid));
}

Which says, allow read if the current users id is present in the Users node.

Hareesh
  • 6,770
  • 4
  • 33
  • 60
  • I tried the suggestion, same result. The issue isn't really that part of the permissions. It operates correctly as long as I only request a single document at a time. But when I need all documents, because some are denied by the query they all fail. I was hoping I can perform a rules operation that bypasses the security rules, For example check an existing value in the document that the request can't read. I need the query to work as a filter before asking Firestore for the data. – user1019416 Nov 15 '17 at 19:08
  • firebase not suggesting to write rules at collection level. do you have any other rules written, which may interfere this rule. – Hareesh Nov 15 '17 at 19:13
  • Not sure, I don't have any of permissions besides requiring auth. I think I'm just going to change the structure. I just wish their was a good example of querying some documents with permissions matching the query. – user1019416 Nov 15 '17 at 20:03