I have a Firestore collection named 'users' that stores user information. Within this collection, there is a subcollection named 'shops,' containing documents listing the shops each user is permitted to access. The 'shops' subcollection includes a field named 'shopId,' which serves as a unique identifier for each shop.
Each incoming read request contains a 'shopId.' I am looking to create a Firestore security rule that validates each incoming request. Specifically, the rule should verify whether the 'shopId' in the incoming request matches the 'shopId' in the 'shops' subcollection of the user document associated with the request, then grant read permission to document from any collection with shopId matching the client request.
Here is my code, but are not working.
service cloud.firestore {
match /databases/{database}/documents {
// Allow read access to user documents if conditions are met
match /users/{userId} {
allow read: if request.auth != null &&
// Check if the user document exists and if the 'shopId' in the request matches the 'shopId' in the user document
exists(/databases/$(database)/documents/users/$(request.auth.uid)/shops/$(request.data.shopId)) &&
request.data.shopId == resource.data.shopId;
// Allow reading all documents under any collection for the specified shopId
match /{collectionId}/{document=**} {
// Check if the user document exists and if the 'shopId' in the request matches the 'shopId' in the user document
allow read: if request.auth != null &&
exists(/databases/$(database)/documents/users/$(request.auth.uid)/shops/$(request.data.shopId)) &&
request.data.shopId == resource.data.shopId;
}
}
}
}
Your Firestore security rules seem to have a logical error. To achieve the desired behavior, you need to ensure that the 'shopId' in the request matches at least one 'shopId' in the 'shops' subcollection of the user document associated with the request. Here's an updated version of your rules:
/ Allow read access to user documents if conditions are met
match /users/{userId} {
allow read: if request.auth != null &&
// Check if the user document exists and if the 'shopId' in the request matches any 'shopId' in the user document's 'shops' subcollection
exists(/databases/$(database)/documents/users/$(request.auth.uid)/shops/$(request.data.shopId));
// Allow reading all documents under any collection for the specified shopId
match /{collectionId}/{document=**} {
// Check if the user document exists and if the 'shopId' in the request matches any 'shopId' in the user document's 'shops' subcollection
allow read: if request.auth != null &&
exists(/databases/$(database)/documents/users/$(request.auth.uid)/shops/$(request.data.shopId));
}
}
} }