Firestore read simulation fails, no highlighted line - google-cloud-firestore

So, I typically don't have problems writing firestore rules but I'm coming up short on why this simulation fails.
If you don't want to follow the image link:
Rules:
service cloud.firestore {
match /databases/{database} {
match /server_credentials/{document = **} {
allow read, write: if false;
}
match /users/{user_uid} {
allow read, write;
match /signatures/{sig_id} {
allow read: if request.auth.uid != null && resource.data.access == "public";
allow read, write: if request.auth.uid == user_uid;
}
match /identity/{credential} {
allow read, write: if request.auth.uid == user_uid;
}
}
match /signatures/{sig_id} {
allow read, list;
allow write: if false;
}
}
}
Auth details:
Google as provider and foo as the uid.
I'm testing a simple read to users/foo
Any help would be quite nice.

This line is incorrect:
match /databases/{database} {
It should be this:
match /databases/{database}/documents {
This mistake is causing none of your rules to apply at all, and all access is being rejected by default.

Related

How To Add Firebase Rules To Specific User To read And Write And all other User only read?

I Have Created firebase and flutter app and google is sending me emails saying firebase rules are not good. How do I make those rules better? I want to give permission to login users to read and my account to read and write permission.
I hope that will help you.
service cloud.firestore {
match /databases/{database}/documents {
// Make sure the uid of the requesting user matches name of the user
// document. The wildcard expression {userId} makes the userId variable
// available in rules.
match /users/{userId} {
allow read, update, delete: if request.auth != null && request.auth.uid == userId;
allow create: if request.auth != null;
}
}
}
This is a correct way you can secure database.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Line below secure whole database so users are not alowed to create any new collections etc.
match /{document=**} {
allow read, write: if false;
}
match /app/{dataId} {
allow read: if true;
allow write: if isAdmin();
}
match /posts/{dataId} {
allow read: if resource.data.isPublic == true || isAdmin();
allow write: if isAdmin();
}
}
}
function isAdmin() {
return request.auth.token.admin == true;
}
Users don't have any .admin variables. You have to assign them using firebase functions. Read about custom claims.

Debugging firestore security rules with emulator does not work

I have written some firebase rules, using firebase emulator. I tried to debug the request which I am sending to the rules, using debug() function. Yet it doesn't print anything. My rules:
function printResource() {
return debug(resource) || true;
}
match /users/{userId} {
allow read, delete: if something....;
allow create: if printResource() && userIsAuthenticated() && userOwnsResource(userId) && debug(isUserNameAvailable(debug(request))) && getAfter(
/databases/$(database)/documents/usernames/$(request.resource.data.username)
).data.owner == userId;
}
I tried as well the following:
match /users/{userId} {
allow read, delete: if something....;
allow create: if debug(userIsAuthenticated()) && debug(userOwnsResource(userId)) && debug(isUserNameAvailable(debug(request))) && getAfter(
/databases/$(database)/documents/usernames/$(request.resource.data.username)
).data.owner == userId;
}
Nothing is being printed. My debug() function is not working, but I don't know why. Is there another way I can print my resource object?

firestore rules, permission errors

Im trying to figure out how the rules in Firestore work, and have stumbled upon a problem I cant quite figure why is failing.
When using the Firestore Rules Playground and do a get request for a document in /apps, I get the following error: "Error running simulation — Error: simulator.rules line [10], column [14]. Null value error."
And from the app im getting: FirebaseError: Missing or insufficient permissions
The location in trying to get: "/apps/0aKQw0MiRzEbrLDvsnI3"
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if isUserAuthenticated();
}
/* Functions */
function isUserAuthenticated() {
return request.auth.uid != null;
}
}
}
The thing im trying achieve is to allow read access for all document, and only write access if a user is signed in
I have no idea why it's failing on a get request?
If I'm not mistaken the way you added the read condition seems to be incorrect. Perhaps try this and see if it works for you.
match /databases/{database}/documents { match /{document=**} { allow read: if true, write: if request.auth != null && request.auth.uid!=null }

Firebase Security rules to restrict access on all paths but one?

Question:
For the different top-level firestore collections below, how to restrict access to all but one of the paths?
We are building a data schema in Firestore to support a chat app for teachers across multiple schools.
The top-level firestore collections include:
/siteAdminUsers
/schools
/schools/{schoolId}/teachers
/schools/{schoolId}/chats
Below is the security rules setup we are trying now - where we check for:
valid user auth
expected value exists in userClaim variable request.auth.token.chatFlatList
However, the read listener for /messages is being blocked.
Error message:
FirebaseError: [code=permission-denied]: Missing or insufficient permissions
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null
&& request.auth.token != null
&& request.auth.token.chatFlatList.val().contains($discussionId);
}
}
Details
We are using cloud functions for all data read/write, so for almost every case we can just block all client access.
The one exception is for the chat discussions, where we need to set a snapshot listener in the mobile client to know when there are new messages.
Sub-collection notes:
At a school, there are discussion sessions for school staff (teachers, admins, etc)
/schools/{schoolId}/chats/{discussionId}
Where each discussion-document contains:
list of participant teacher ids
subcollection for actual messages where each document is an indivual posted message:
/schools/{schoolId}/chats/{discussionId}/messages
User Claim code from Cloud Function
Looking at the cloud function logs, we have verified that the userClaim is being set.
return firebaseAdmin
.auth()
.setCustomUserClaims(
uid, {
chatFlatList: 'id1 id2 id3'
}
);
UPDATE #1
Tried the following variation where rules skip/omit the check on userClaim and auth.token.
However, still same permission error.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null;
}
}
}
I think the issue here is that you are writing a rule on the collection called messages.
All match statements should point to documents, not collections.
https://firebase.google.com/docs/firestore/security/rules-structure
You should try adding /{document=**} after your path to messages, something like:
match /schools/{schoolId}/chats/{discussionId}/messages/{document=**} {
allow write: if false;
allow read: if request.auth != null;
}
This worked for me if I wanted to read and write all collection but not one collection named "backStage";
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{collection}/{document} {
allow read: if true
allow write: if (collection != "backStage");
}
}
}
Here's a solution (seems to be working), which includes the check on chatFlatList user claim variable (from original question) for a substring :
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null
&& request.auth.token.chatFlatList.matches(discussionId);
}
Figured this out thanks to:
Firebase storage rules based on custom parameters
Here the post shows there is not any $ notation to access the path var. I recall seeing this in a security rules example code example - maybe it's specific to database tiers?
https://firebase.google.com/docs/reference/security/storage/#string
https://regex-golang.appspot.com/assets/html/index.html
Trying some example inputs here, to get an understanding for how to create the regex's.

Q: Firestore Security Error: Missing or insufficient permissions

I'm currently using Firestore for database and ran in to insufficient permission error. What I don't understand is why isPartner() will work when my path is
users/{uid}
but give me permission error when it's
object/{objectID}
Security Rules
service cloud.firestore {
match /databases/{database}/documents {
match /users/{uid} {
allow read: if isSignedIn();
allow write: if isOwner(uid) || isPartner();
match /object/{objectID} {
allow read, write : if isPartner() || isOwner(uid);
}
function isOwner(userID) {
return request.auth.uid == userID
}
function isPartner() {
return resource.data.partnerUID == request.auth.uid
}
}
}