SeriousLee
SeriousLee

Reputation: 1371

Firestore: Return only documents where rule condition is met

I get a FirebaseError: Missing or insufficient permissions. error when I try to retrieve all documents with a specific property from a collection. To be clear, this is on the Firestore Rules level, not application level - I'm not struggling with .where() queries.

My firebase rules currently look as follows:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /projects/{project} {
      allow read: if resource.data.visible == true; // This condition seems to be the problem child
      allow write: if false;
    }
  }
}

I've confirmed that resource.data.visible == true is what's causing the issue by swapping it out for request.auth != null, in which case no errors are thrown and it returns all documents.

Here's a screenshot of one of my documents:

enter image description here

The other censored document has its visible property set to false.

And here's my (JavaScript) code that I use to access Firestore:

firebase.firestore().collection('projects').onSnapshot(snap => {
  console.log('snap:', snap);
}, err => {
  console.error(err); // Here's where the error gets thrown
});

Let me know if I need to include any additional information.

Upvotes: 1

Views: 1309

Answers (2)

robsiemb
robsiemb

Reputation: 6354

You are attempting to use a Firestore security rule as a filter, but security rules are not filters. The query is evaluated against its potential result set, and if it could possibly return documents that the client does not have permission to read, the entire query will fail.

However, you can solve this by also adding the necessary constraint to your query. For example (I have not tested this exact code, but this should be close to what you need):

firebase.firestore().collection('projects').where("visible", "==", true).onSnapshot()

If you need more details, basically this exact example (doing a query with a security rule restricted by a field on the document that defines its visibility) is in the security rules documentation.

Upvotes: 3

Frank van Puffelen
Frank van Puffelen

Reputation: 598740

Firebase security rules don't filter your data on their own. Instead they merely check that any operations your application executes are allowed according to the rules.

Since your code tries to read all projects, the rules check if that is allowed. And since the rules specify that users can only read projects that are visible, the read for all projects is rejected.

When you want to allow partial access to the data in a collection, you'll need to write both rules and code to make this work. In your case, you'll want to filter your code too.

firebase.firestore().collection('projects').where('visible', '=', true)

Upvotes: 1

Related Questions