Firebase Realtime Database rules to allow a single user Write access - firebase-realtime-database

My current Android Application makes use of the Firebase Realtime Database.
I am struggling with the security Rules as I wish to allow only a Single User to be able to Write data while allowing any authenticated user to read data.
I have set these rules but am unsure if they are secure enough...
{
"rules": {
".read": "auth != null",
".write": "auth.uid === 'xxxxxxxxxxxxxxxxxxxxxxx'"
}
}
Where 'xxxxxxxxxxxxxxxxxxxxxxx' is the specified user I wish to allow to write data.
Is a users uid a constant value?
What does the "Authenticate" option manage when clicking on the Simulate button when testing out new rules?

Once a user's UID is generated, it will never change. So checking the UID in the security rules is indeed a common way to ensure only that specific user has a certain permission. I do this on almost every project when getting started for the initial (admin-type) users.

Related

How to get the password of the current user - Swift Firebase

I want to know, is there a way to retrieve the current user's password? Or just check if his password != "acertainvalue". I'm speaking when the current user is connected through Firebase authentification. Thank you
There is no way to get the current password from the Firebase Authentication API as that would be a big security risk.
I'd also in general recommend against persisting the user's password as plaintext anywhere yourself, for the exact same reason.
If you need to check the user input against a specific value in your code, you should do that check right after you get the input from the UI - and before passing input on to Firebase.

How to create different user groups in Firebase?

I am making a point of sale app, using Xcode.
I want this app to keep track of stock items, allow users to search stock, scan stock, add or lookup stock using a barcode. Items of stock will be stored in a users 'store'.
I want to have three types of users:
A manager user, who creates a store and has full access to the store. He can manage all of the 'employee users', such as deleting their access and employee users must be invited by him to join his store using a unique code. He will have specific abilities that 'employee users' do not such as the ability to add and edit stock.
What a manager account would look like
A employee user, who has limitations. (e.g. cannot see edit users page and not option to edit stock that manager user has).
What a Employee account would look like
A shopper user who can only see a store and the items in a store.
What a shopper users account would look like
The attached UI design should show what I mean. As you can see, the manager user has a manage employee tab that I wish only he can have and the other users do not. The manager has also got the option for more details when looking at stock, while the employee user does not. The shopper account has only got access to two functions, looking up a store, and checking the stock in a store.
So my question is,
How do I code three different types of users in Firebase for my app?
& How do I show them only options that I want to show them while showing other options to other users?
This is an incredibly broad topic and lots of it depends on how you implement the various parts of your app. Below is one of the many possible answers, just in an effort to get you started with some links.
If your app stores its data in one of Firebase database offerings (Realtime Database, or Cloud Firestore), or if it stores files in Cloud Storage through Firebase, then you'll likely want to store the role of each user as a custom claim in the profile of that user.
The Firebase Authentication documentation shows how to set such custom claims, for example how to set the admin property of a user to true from a Node.js script:
admin.auth().getUserByEmail('user#admin.example.com').then((user) => {
// Confirm user is verified.
if (user.emailVerified) {
// Add custom claims for additional privileges.
// This will be picked up by the user on token refresh or next sign in on new device.
return admin.auth().setCustomUserClaims(user.uid, {
admin: true
});
}
}).catch((error) => {
console.log(error);
});
Similarly you could set your user roles in a role property. Then you can check in the server-side security rules of the Realtime Database, Cloud Firestore, or Cloud Storage if the user has a role that allows them access to the specific data they're trying to access.
In the client-side code you can then decode the user's token to get access to the same claims and optimize the UI for them
Frank's answer is the correct one but I wanted to add a very simple additional piece of information. If you store users information, (DOB, nickname etc) in a /users node (as many Firebase apps do) simply add the role within that node
users
uid_0
name: "Larry"
role: "manager"
uid_1
name: "Curley"
role: "employee"
uid_2
name: "Moe"
role: "shopper"
When a user logs in, read their node from the users node and the app will then know what kind of user they are and display the appropriate UI.
You can also leverage that within Firebase rules to control what each role can access.

Firebase Auth only for devices using my app

I have a question about Firebase Auth.
I'm working on my app and, even if I downloaded Firebase Auth Protocol using Pods, I realized that I really don't need them.
The aim of my app is to show some random quote about users but I don't need to Auth them 'cause I don't want and I don't need to implement an Auth system.
In few words: if you're using my app, you can submit a random quote anonymously.
How do I have to set the Authentication from Firebase Dashboard in order to allow ONLY the users who use my app to do that? How can I prevent people not to submit info if they're not using an iOS device?
You could have the user sign in anonymously and have a rule in Firebase that you have to be signed in to post quotes. If you also have to be signed in to read the quotes the rules would look like this.
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
Doing this through anonymous authentication is a good first step, but the rules in Casper's answer are quite easy to bypass. If you don't have a better authorization schema for your users, I recommend implementing the newly introduced Firebase App Check to ensure requests are only allowed from apps that are registered in your Firebase project.

How to restrict read only to Authorized users of Firebase Database?

I am modifying the FriendlyPix Firebase sample app so that only authenticated and authorized user can read data under the node. Following is the Database rule for my real-time DB
"posts": {
// ".read": true, COMMENTED OUT
"$postId": {
".read": "auth.uid === data.child('author').child('uid').val()",
".write": "!data.exists() || data.exists() && auth.uid === data.child('author').child('uid').val()",
//more code
The issue is that now a logged-in user can't read any posts (not even the ones he posted). I am using Firebase UI and Google login. What am I doing wrong?
Without the line you commented out, nobody can read from /posts. To be able to query /posts. you must be able to read from it.
This a common recurring roadblock for developers new to Firebase: rules cannot be used to filter data. I recommend you read up on that in the Firebase documentation and in the many questions on the topic.
Firebase queries are all or nothing. If you are listening to the "/posts" node of your Firebase database, a user will only get ANY data if the are authorized to see ALL of the data under that node. Your rules do allow for an author to read their own posts, but not any others. This means that the entire query will result in an authentication error.
Anytime auth is not null, it means the user is authenticated. As any authenticated user should be able to read a post, just putting read to "auth != null" will suffice. Note that this only allows logged in users to read posts, not to edit them.

where to store user info after login to swift ios app

I'm creating simple user login at the beginning of my app. After user submits correct username and password, my script from server should return some parameters which I should store in some sort of local database, and check for these parameters every time when new view appear/loads.
My questions are:
1) which type of local "database" should I use, which one is secure so no one else from "outside" can access it, because if someone could than he could set my logins by himself (keychains, user defaults etc.)?
2) which parameters should I return from server, which one of them are essentially from security when checking if user is logged in - I'm thinking of username and the token - if user is successfully logged in, than server script should create some type of token which will be stored in online database. Every time user makes some request from app to the server than token is checked, if it exists in app and if it exists in server database and if they are equal.
3) How should I check if user is logged in when new view is loading in the app - should I just check if variables exists (for example in Keychains) or should I connect to the server and check every time server database?
for storing sensitive user data(password, api token, email) you should always use Keychain for this purpose.In other hand there is Realm also offer secure way to store your data.Its easy to use, you just need wrap data objects with realm base(Object) class and mark properties with dynamic attribute.For basic login system i think user name, email and api token good enough.But depends on api needs you can include here phone number, birthday etc.For checking user authorization I think validating api token good enough in most case.
There is also most secure techniques to improve data safety like keep database property names in keychain.Hashing sensitive data parts in api calls.Last thing you need use https for api communication.

Resources