I am having an issue where my Firebase Firestore Rules are denying authenticated users requests to the database. I am not great with Firestore rules so it is likely something I am doing wrong on my side.
Here are my Firestore Rules:
service cloud.firestore {
match /databases/{database}/documents {
match /{userID} {
allow read: if request.auth.uid == userID;
allow write: if request.auth.uid == userID
}
match /payment_options{
allow read: if request.auth != null;
allow write: if false
}
match /logs{
allow read, write: if false
}
}
}
Check the attached image for a snapshot of my firestore data where the red lines represent UserID's retrieved from Firebase Authentication.
I am using the Flutter Firestore and Firebase Auth SDK's, and I make sure to only get/set the database docs AFTER the user has signed into the flutter app, but I keep getting the follow exception:
Exception:
[cloud_firestore/permission-denied] The caller does not have permission to execute the specified
operation.
Here is my App Tree that listens for Auth state changes and routes the user to the login page if they are not logged in, and routes them to the main page once they have logged in (Firestore operations only happen AFTER the main page):
class AppTreeWidgetState extends State<AppTreeWidget > {
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Auth.currentUserStream,
builder: (context, snapshot){
if(snapshot.hasData) {
//TODO: Tell firebase to use the Signed in user to authenticate requests
//to the Firestore Database
return const MainPage();
} else {
return const LoginScreen();
}
}
);
}
}
Any help or pointers to get this up and running would be much appreciated!
I expected that the Auth and Firestore SDK's would interop and my Firestore calls would already be authenticated once the user signs in Using the Firebase Auth SDK - am I wrong here? Do I need explicitly authorize the calls to the Firestore database with the information retrieved from user sign in?
i am not sure about how did you are calling and how is you data str. but if you are sure about that the user is authenticated successfully then there is no need to pass additional information to firebase while making call to database as the auth status is always attached to the request automatically .
my suggestion is to try with {documents=**}
it is a wildcard that matches any document within a specified path.
service cloud.firestore {
match /databases/{database}/documents {
match /{userID}/{documents=**} {
allow read: if request.auth.uid == userID;
allow write: if request.auth.uid == userID
}
match /payment_options/{documents=**} {
allow read: if request.auth != null;
allow write: if false
}
match /logs/{documents=**} {
allow read, write: if false
}
}
}
Please before implementing consider going thought following
If you want rules to apply to an arbitrarily deep hierarchy, use the recursive wildcard syntax,
{name=**}
. For example:service cloud.firestore { match /databases/{database}/documents { // Matches any document in the cities collection as well as any document // in a subcollection. match /cities/{document=**} { allow read, write: if <condition>; } } }
When using the recursive wildcard syntax, the wildcard variable will contain the entire matching path segment, even if the document is located in a deeply nested subcollection.
For example, the rules listed above would match a document located at
/cities/SF/landmarks/coit_tower
, and the value of the document variable would beSF/landmarks/coit_tower
.
so use wildcard only if you are assures about a collection that may/may not contain other nested collection and documents and all lies and should follow the same security level (conditions).
for more simple example if you have str. like /allUsersData/{userId}/notPublic/{docId}
and you wright rules as follow
match /allUsersData/{documents=**} {
allow read: if request.auth != null;
allow write: if request.auth != null;
}
that means you are giving the auth user permission to not just read the document (userId}
under the collection allUsersData
but also to all the other collection and documents in that tree, that means also to the collection named notPublic
.
so when using wildcard
please keep in mind that the rule will be apply to all of the nested data tree.
as i don't see the exact implementation here . if it did not solves then you need to provide additional implementation details.