I'm new to using Firebase (I'm using react-redux-firebase, but not sure if that's relevant to this question). I'm having an issue using these standard auth rules:
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
This is user UID as shown in the Firebase Authentication dashboard:
But if I print out the data associated with the profile/account, I get this UID:
Because of this mismatch, the logged in user is unable to read or write to the firebase instance.
Why is there a mismatch in UIDs? How can I solve this issue?
UPDATE:
It looks like the 1091103… UID is provider-specific and not relevant in this case? Can't confirm that for sure.
This may be the actual auth UID (I'm new to this, so still trying to figure out what's what):
In this case, this UID matches what is seen in the Firebase console. If they match, then what would be the cause of the permission denied errors?
ANOTHER UPDATE:
Here's the user node. You can see the UID as the key:
This is the rule you can do right now
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
if you want to check like below
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
you need to store the users to realtime database while register. with their auth.uid as key.
Related
I'm trying to create a rule for create/access the FRD data based on authenticated user. But am getting an error where running the Rules Playground
What I want is, Users are creating the categories. So Users is able to only read their categories and update those categories.
Rule:
{
"rules": {
"users": {
"$uid": {
".write": "auth != null && $uid === auth.uid",
".read": "auth != null && $uid === auth.uid"
}
},
"categories": {
"$uid": {
".write": "auth != null && $uid === auth.uid",
".read": "auth != null && $uid === auth.uid"
}
}
}
}
Auth Users:
Realtime Database
Categories
Users
Categories Write function in Flutter
String uId = await userId();
final databaseRef = FirebaseDatabase.instance.ref('categories');
var data = await databaseRef.get();
var index = data.children.length;
await databaseRef.child('$index').set(<String, dynamic>{
"name": categoryBody.name,
"description": categoryBody.description,
"uid": uId,
"id": index,
});
Error
Is there anything wrong with the rules that am applying?
I tried to replicate your issue, but I can able to successfully test rules without errors.
The rules you are using are for authenticated users but you are testing for unauthenticated users. Means you have not enabled Authenticated field.
And you have to enter /categories/uid instead of /categories under the location and you should enter uid under Firebase UID field. You may have look at below screenshot.
You can refer this tutorial for more information.
When you're using the following security rules:
"categories": {
"$uid": {
".write": "auth != null && $uid === auth.uid",
".read": "auth != null && $uid === auth.uid"
}
}
It means that you allow the user to write/read to/from every child that exists under your categories/$uid node. So when you try to apply those rules to your actual database structure, it's the expected behavior to see that Firebase servers reject the operations since it doesn't find any $uid level in your database schema. To solve this, you have to remove that extra $uid level from rules like this:
"categories": {
".write": "auth != null",
".read": "auth != null"
}
And this is because those category objects exist directly under the categories node and not under categories/$uid.
Looking to make my server more secure at this moment my Firebase Security Rules are
{
"rules": {
".read": "auth.uid != null",
".write": "auth.uid != null"
}
}
The above rule would allow anyone that has a user credential to change data. This would make the data insecure therefore what I am looking to do is change the security rule so that only the owners of the data are allowed to change their information. please note that my data structure on the real database has two nodes
Please see the attached image below
We just want to secure posts the code I am trying to run and it's not working
{
"rules": {
"posts": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
The error I am getting is simulated read denied
I have a database like this:
The first key is the userId, has to be connected, and the next keys only him can read and write. How I can manage the rules to be safe and no one can't see the key of each other ? I begin with that but I don't think is enough
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
Because you are using the user ID as a key you can use it in your rules to make sure users can only read/write to their own nodes like this:
{
"rules": {
"$user_id": {
".write": "$user_id === auth.uid",
".read": "$user_id === auth.uid"
}
}
}
For more information you can take a look at the firebase docs about User Based Security and Securing Data. For a more extencive answer about linking users to their data you can take a look at my answer here.
I'm building a new application using firebase authentication and realtime database. I understand how to secure a location in the database so that only a specific authenticated user can write to it, as per the documentation:
{
"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"
}
}
}
}
I want to secure a location for one or more users. I'm not sure whether that is possible and if so, how would I structure the data. The data is a list of shopping items that one or more users can update, while all other users can view the shopping items. All users are authenticated, but one or more of them is designated as the shopper, so they are allowed to add and remove items.
Thanks
Craig
Just in case someone stumbles across this, a member of the firebase forum was able to answer the question and I ended up with the following database rules:
{
"rules": {
"users": {
".read": "auth !== null",
"$udser_id": {
".write": "$user_id === aith.uid"
}
},
"shops": {
"$shopID": {
"items": {
".read": "auth != null",
".write": "data.parent().child('shoppers').child(auth.uid).exists()"
},
"shoppers": {
".read": "auth != null",
".write": "root.child('users').child(auth.uid).child('scheduler').val() == true || data.child(auth.uid).exists()"
},
"boxes": {
".read": "auth != null",
".write": "auth != null"
}
}
}
}
}
This was based on an article here: https://firebase.googleblog.com/2016/10/group-security-in-firebase-database.html
I've database structure like
appointments
[$userId]
[$appointmentId]
message:"something"
date:"14/12/2015"
users
[$userId]
name: Hardik
email: hardikmsondagar#gmail.com
And I'm using angularfire library of Firebase, I'm trying to restrict read operation based on uid ( means a person who created appointment only can read that). I've tried following security rule
{
"rules": {
"appointments": {
"$userId":{
"$appointmentId":{
".read": "auth.uid==$userId",
".write": true
}
}
},
"users": {
"$userId":
{
".read": "auth!=null && $userId === auth.uid",
".write": "auth!=null && $userId === auth.uid"
}
}
}
But end up on this error
Error: permission_denied: Client doesn't have permission to access the desired data.
I'm trying to access all the user's appointments using following code
var ref = new Firebase("https://<FIREBASE-APP>.firebaseio.com/appointments/"+uid);
$scope.appointments = $firebaseArray(ref);
Set rules for the $uid wildcard, to read all the children.
"appointments": {
"$uid":{
".read": "auth.uid == $uid",
".write": "auth.uid == $uid",
}
}
The $uid wildcard sets permissions for the entire list, whereas the $appointmentId wildcard sets permissions for each individual item.
But Security Rules cascade, so you only need to set the rules for the top level.
Read the docs on cascading for more information.