Firestore security rules using uid from database - firebase

I am trying to set up some security rules for my Firestore database, I'm using for my Android and iOS app. My database is open for all users to read and write (to a certain degree), but I don't want the data to be able to be deleted/hacked from writes outside the app, so I need some security rules. What I understand is that: allow read, write: if request.auth.uid != null, is not enough, since it can be easily faked from outside the app.
Here is what I want to achieve. When a user signs in (even anonymously) the app sends his unique uid to a collection in the database. This collection stores all the uid's of all users, where the document name is the uid.
Now in the security rules, I want to only allow read and writes of my database, to users whose uid is stored in this collection. After trying to read about it, I still don't know how to write such a security rule. Could you help? How can I reference this collection field in the security rules, and search if there is a document names with the uid of the requester?
For example, I would like:
match /cities/{city} {
allow read, write: if request.auth.uid = userIdInDatabse()
}
I do not know how to write the function, userIdInDatabase(). This needs to be a function written in the security rules, which takes the request.auth.uid and checks if that uid of the request is in the collection of uid's that I have made from the app. If the uid of the request is in the database, the function will return true. If the uid of the request is not in the database, it will return false. How do I write such a function?
Thanks so much! I hope its clear.

Related

exposing firebase credentials with user information

hey i am developing a web application for a public project using firebase and I am worried about exposing user emails.
The basic idea of the website is:
1.) input -> user provides email and some information
2.) calculations happen on the server and information is written to firestore (admin sdk)
3.) output -> user receives a link in their email to view the results
the information i store is essentially
taskID {
input,
email,
output
}
users only have read permissions
my firebase rules as follows:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if true;
allow write: if false;
}
}
}
i know the firebase credentials are somewhat exposed on the client, so I am worried that somebody can use them to list all tasks, then iterate over all tasks to get the emails and the user provided inputs.
Is this possible at all? Would i have to have a different collection which can only be read by admins, then reference the fields?
taskID {
input,
email : privateCollectionID,
output
}
privateCollectionID {
email
}
Thanks
Your current rules allow anyone and everyone to read all data in your database at will.
If that's not what you want, you'll need to structure your data in a way that meets what you do want.
If you want some data to be publicly readable, and other data to be only readable by the owner of that data, you will need to separate that data into different documents/collections and apply different rules to them.
For an example, have a look at the Firebase documentation for public/private access in security rules.
You could use a Callable Cloud Function that you call from the front-end passing the desired email.
The CF queries the collection to find the document corresponding to the email and returns the document data.
Since the Admin SDK bypasses security rules you can deny read access to this collection in the security rules.
Note that:
This will not prevent users to test for a certain email existence but it will prevent them getting direct (one shot) access to the entire emails list.
The response time will be a bit longer compare to a direct query to Firestore via the JS SDK. More details in this article.

Are firestore rules case sensitive or does my path contain an error?

I am new to firestore rules and I encountered a glaring problem.
My rules look like this:
If I uncomment either or both the sections, and comment the part with (document=**), all project calls to the firestore realtime database will fail because of permissions. I cannot figure out why. In all documentation this is the preferred way. Is it case sensitive? I know it is not the auth part that fails, because if I leave the rules like in the image, all project calls work.
For clarity, this is what the database structure looks like (yes, Projects has a capital P):
Are Firestore rules case sensitive?
Yes, the collection/document IDs are case sensitive.
match /{document=**} {
allow read, write: if request.auth != null;
}
The above rule allows any user logged in with Firebase authentication to read and write to any collection in the database. If you still get permission errors, check if the user is logged in or no.

Firestore Security Rules for specific user that was added in the Firebase console directly

I have this user where I added it directly from the firebase console, hence, it is not in any user collection.
Is it possible that only this specific userID can access collections of orders and products?
If it's only one user then you can restrict read access of those collections to that specific UID using the following rule:
match /orders/{orderId} {
allow read: if request.auth.uid == "firebase_user_id";
}

Can we have a rule just only write permission without read permission in firebase firestore?

As the title, I just want an authenticated user is allowed to write to a collection in firestore, but is not allow to read data of the collection. Is it possible to do that ?
Yes, it's possible. Simply do not grant read access in the rule for that collection.
match /collection/{id} {
allow write: if request.auth != null;
}
This is easy to test for yourself using the rules simulator in the Firestore console.

Firebase rules security warning

I'm getting the following message in Firebase:
The Cloud Firestore "(default)" database of your project contains
rules that are not secure.
But I have the rules as the documentation says and I don't see any other option. What I want is that anyone can read, but just logged in users can edit content.
These are my rules:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if true;
allow read, write: if request.auth.uid != null;
}
}
}
With these rules any authentication user can write all documents in your database, including overwriting documents that were created by other. You're also allowing everyone (no matter if they're authenticated) to read all data in the database, which seem much broader than most apps need. While these are close to some of the default rules you can start with, it is typically not enough for a production app, which is why you receive the warning.
You'll typically want to further lock down access to the database. For example, you might want to ensure that users can only write documents that contain their own UID in a specific field. That way you'll always know who created a document, and can use that to control access to that document.
If you are certain this is the minimum data access that your app requires to function, you can disable the warning emails in the Firebase console. But as said before, in my experience this type of access seems much broader than what I typically see in well functioning, and well protected, apps.

Resources