Let’s say I have a collection called dogs and inside that have a list of documents like dogA, dogB, and so on. I need to give access to a web application to only read each document. But dogs collection should be locked. It is as follows.
/dogs/dogA → should be accessible
/dogs/dogB → should be accessible
You can achieve this using the following security rules:
rules_version = ‘2’;
service cloud.firestore {
match /databases/{database}/documents {
match /dogs/{document=**} {
allow read: if true;
}
match /dogs {
allow read: if false;
}
}
}
This rule first sets the version of the security rules to 2. It then defines two match statements. The first match statement matches all documents in the dogs collection. The second match statement specifically targets the dogs collection itself.
The first match statement allows read access to all documents within the dogs collection. This means that the web application will be able to access individual documents like /dogs/dogA or /dogs/dogB.
However, the second match statement denies read access to the dogs collection as a whole. This ensures that the web application cannot list all the documents in the dogs collection or perform any operations on the collection directly.
In essence, this rule configuration allows the web application to read individual documents within the dogs collection but prevents it from accessing or listing the entire collection.
The code you provided is attempting to read a single document (dogA) from the dogs collection and then trying to list all documents in the dogs collection.
he code should be able to read the individual document (dogA) but should fail when trying to list all documents in the dogs collection.
However, the problem is that the rule match /dogs/{document=**} { allow read: if true; } is too permissive. It’s allowing read access to all documents and subcollections under /dogs, which inadvertently includes the collection itself.
To fix this, you should be more specific with your rules. Here’s the corrected security rules:
rules_version = ‘2’;
service cloud.firestore {
match /databases/{database}/documents {
// Match any document inside the ‘dogs’ collection
match /dogs/{dogId} {
// Allow read access to individual documents
allow read: if true;
}
// Deny list access to the entire ‘dogs’ collection
match /dogs {
allow list: if false;
}
}
}
I apologize for the oversight. You’re right; Firestore security rules doesn’t seem to
have a specific list property.
The issue is that the read rule encompasses both get (retrieving a single document) and list (listing all documents in a collection). To differentiate between them, you should use the get and list properties explicitly.
Here’s the correct way to set up the rules:
rules_version = ‘2’;
service cloud.firestore {
match /databases/{database}/documents {
// Match any document inside the ‘dogs’ collection
match /dogs/{dogId} {
// Allow get access to individual documents
allow get: if true;
}
// Deny list access to the entire ‘dogs’ collection
match /dogs {
allow list: if false;
}
}
}