Firebase admin and user account - android

I am building an Android app with firebase. Simple users would sign in and add data to the database. Users would be able to see only their own data. Then I need to have a single Admin account that sees all data in the firebase database. How should I go about it?

Did you secure your database in any way yet? If not, I recommend getting started with the documentation for Firebase security rules.
I typically secure my database as shown in the section on securing user data and then have a list of UIDs in the database for users with special permissions.
So with a JSON structure like this:
users
Power3000Uid: { ... }
PufUid: { ... }
admins
Power3000Uid: true
And security rules like this:
{
"rules": {
"users": {
"$uid": {
".read": "auth.uid == $uid || root.child('admins').child(auth.uid).exists()"
}
}
}
}
In words the .read rules is: "you can read this data if you're the owner of it, or if you're an admin". In the sample above this means that you can read anyone's data, but I can only read my own.
Depending on your exact needs, you'll need to repeat the admin-clause in various places in the database, or (what I usually do) just have it once at a high level in your JSON tree.

Related

Firebase Security Rules for a data sharing app

I am working on a simple react-native To-do app with sharing features. I am using Firebase Storage for storage and sharing. However, I am a beginner to Firebase and couldn't understand how to proceed. My requirements are as follows
Each user can add/remove/edit their own database entry.
User A should be able to share some of their To-dos with User B. The share can be in either view or edit mode (exactly like a Google Drive file).
An option to permanently allow User B to see all future view or edit mode for any new to-dos. Basically, an option to allow or disallow User B to see the data.
My attempt:
Bullet 1 can be achieved simply by
// These rules grant access to a node matching the authenticated
// user's ID from the Firebase auth token
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
source
For Point 2 and Point 3, I plan to have a separate JSON file accessible by all the users. So when user A gives edit access to some of its data to User B, the JSON file for user B should be updated with A's uid. I am not able to write security rules for this because I am not aware if we can write rules to get data from a JSON file. Also, this method is not very good in my opinion, as some attacker may flood User B's JSON file with garbage entries and in fact can delete the existing entries also.
Any help to achieve this Google Drive-like sharing feature for Firebase storage will be appreciated. Thanks!
You can allow who can write or read particular path in rules
if your database looks something like this:-
your rule can look something like this:-
"rules": {
"$uid":{
"$todoid":{
"todoitem":{
".read":"$uid == auth.uid || data.parent().child('sharedwith').child(auth.uid).val() === 'editor' || data.parent().child('sharedwith').child(auth.uid).val() === 'editor'",
".write":"$uid == auth.uid || data.parent().child('sharedwith').child(auth.uid).val() === 'editor'"
}
}
}
}
you can follow this blog post to understand better:- https://firebase.googleblog.com/2016/10/group-security-in-firebase-database.html
Am glad that you are trying to work with Firebase Realtime Database Rules.
Firstly I guess you understood concept of rules in a different way. The rules in firebase is not built to have User specific data control. These rules are used to give certain data access to certain type of users
For example :
You can give R/W permission to specific child to the users who are only Authenticated. For the one who not authenticated we can restrict the access
Main motive of this Rules tab is to avoid Data breaching from a 3rd party access
To know more about firebase rules please watch video in the given. link
https://www.youtube.com/watch?v=PUBnlbjZFAI
You can also see this Documentation
https://firebase.google.com/docs/database/security

Firebase - Predefined User list & Phone Number Authentication

I am working on one the Android APP & want to integrate it with the Firebase & it's Realtime Database. I have a list of 1000 users(Excel) with details like EmpId, EmpName, Team, Mobile Number, etc.
I want to restrict my APP only to the users from this list & also want to authenticate them using the mobile number present in the list against there name.
Can I use Firebase Auth for the above requirement & if yes, how to do that?
If with FireBase Auth, this is not possible what is the alternative solution?
Please help.
Firebase Authentication only allows the users to identify themselves. What you're describing is limiting what users are allowed to use your app, which is known as authorization, and Firebase Authentication doesn't handle that.
Luckily you tagged with firebase-realtime-database too, and authorization is definitely built into that. What I'd usually do is create a top-level node in the database that contains the UID of users that are allowed to use the app:
"allowedUsers": {
"uidOfUser1": true,
"uidOfUser2": true
...
}
Then in other security rules you'll check if the user's UID is in this list before allowing them access to data, with something like:
{
"rules": {
"employees": {
".read": "root.child('allowedUsers').child(auth.uid).exists()",
"$uid": {
".read": "auth.uid === $uid && root.child('allowedUsers').child(auth.uid).exists()"
}
}
}
}
With these rules:
Allowed users that are signed in can read all employee data.
But they can only modify their own employee data.
Of course you'll want to modify these rules to fit your own requirements, but hopefully this allows you to get started.
A few things to keep in mind:
The UID is only created once the users sign up in Firebase Authentication. This means you may have to map from the email addresses you have to the corresponding UIDs. You can either do this by precreating all users, do it in batches, or use a Cloud Function that triggers on user creation to add the known users to the allowedUsers list.
Alternative you can store the list of email addresses in the database. Just keep in mind that somebody could sign in with somebody else's email address, unless you require email address verification. Oh, and you can't store the email address as a key in the database as-is, since . characters are not allowed, so you'll have to do some form of encoding on that.
Also see:
How do I lock down Firebase Database to any user from a specific (email) domain? (also shows how to check for email verification)
Restrict Firebase users by email (shows using encoded email addresses)
firebase realtime db security rule to allow specific users
How to disable Signup in Firebase 3.x
Firebase - Prevent user authentication
I know it's late but for anyone who may be referencing this question, my recommendation is blocking functions. You essentially create a Firebase Cloud Function that can accept or deny requests to make an account. Here's what it could look like:
const functions = require('firebase-functions');
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
var allowedUsers = ['johndoe#stackoverflow.com'];
// if they are not in the list, they cannot make an account
// throwing this error will prevent account creation
if(allowUsers.indexOf(user.email) == -1) throw new functions.auth.HttpsError('permission-denied');
});
This way is better in my opinion because the security rules doesn't have to reference the database. Instead, the security rules can allow requests from any authenticated user, because the only authenticated users are ones allowed by this function.

Setting a Role-Based Access Programmatically

I have developed an app on Android that uses the Firebase realtime database. aka multiple nodes in the DB store various data collected by my app. For Auth, email/password-based Sign-in and Sign-up are working properly. When I sign-up a new user the auth works but that new user then needs to be granted access to the firebase database nodes the app uses. My app needs to grant this new user access to the firebase database nodes required for app interaction.
In other words, how do I programmatically, via my app, change the firebase node-access/security rules in my app (when I currently only know how to change these via the Firebase browser UI)? I do not see methods in FirebaseAuth to do this. So, where do I go from here?
Also, obviously a new user of my app will not have my credentials but they must be able to add access for themselves to my existing firebase realtime database nodes. How do I this?
Here are the rules I have in place today (where my UID is my actual firebase UID):
{
"rules": {
".read": "auth.uid === my UID",
".write": "auth.uid === my UID"
}
}
I now understand I must set rules to allow all authenticated users to read write data in various nodes of my tree. I do not yet understand how to grant access by node and particularly by a specific uid-based node in a tree where there may be many UIDs for each user. As an example, if my tree is root (top), then messages, then a UID for each user, what is the syntax for an authorization rule that will allow the current user/UID read/write the data in only his/her UID under root, messages, his/her user UID?

Firebase rules write fails while read succeeds

I have these rules in my real-time database and cannot figure out why only the .write rule fails, while the .read succeeds. Both the write rule and read rule are the same aside from ".write" and ".read" so if one works, shouldn't the other?
In the 'Users' node all users have a homesteadId value which I'm trying to make sure is == to the uid under the Homesteads node which they are trying to edit.
"Homesteads": {
"$uid": {
".write": "root.child('Users').child('auth.uid').child('homesteadId').val() == $uid"
,".read": "root.child('Users').child('auth.uid').child('homesteadId').val() == $uid"
}
}
The highlighted nodes in the image below are the ones I'm trying to compare to ensure they are equal in order to give read/write access to the user.
I've also noticed that loading the data in my app has slowed down as a result of the above read rule. Now when the user signs in the data doesn't show immediately in its recyclerview as it should, and requires closing the app and opening it again before the data is displayed (or navigating to another view in the app and returning). Do security rules like this affect database query performance?
Thanks!

Firebase - should I recreate 'users'?

Sorry if this seems like a dumb question but the Firebase docs go round in circles.
I'm building an Android app and I'm authenticating users using mAuth.createUserWithEmailAndPassword documented here - https://firebase.google.com/docs/auth/android/start/
That's straightforward and I can set the username, email etc. and its all stored somewhere (I've no idea where as its not displayed in the Firebase console) BUT I'm confused about user based authentication - https://firebase.google.com/docs/database/security/user-security in the examples here (and elsewhere on the net) we see the rules starting with users
{
"rules": {
"users": {
"$user_id": {
// grants write access to the owner of this user account
// whose uid must exactly match the key ($user_id)
".write": "$user_id === auth.uid"
}
}
}
}
As far as I can see in the Firebase console there is no users child node in the database generated automatically from mAuth.createUserWithEmailAndPassword. So my question is should I create this or was a users child automatically created I just can't see it?
Its not a lot of work to implement an additional user child node and store user information there but it seems like a lot of duplication given that the authentication procedure has already stored the user information somewhere. The opposite way to ask this question is can I add the db write rules above and expect them to work if I have authenticated users but never added a users node in the db myself?
Why the docs don't spell this out is beyond me

Categories

Resources