I am trying to create new user after I login with facebook/google, but getting error with:
error_handler.js:46 EXCEPTION: Uncaught (in promise): Error:
PERMISSION_DENIED: Permission deniedErrorHandler.handleError #
error_handler.js:46next # application_ref.js:291schedulerFn #
async.js:89SafeSubscriber.__tryOrUnsub #
PERMISSION_DENIED: Permission denied
my rules are:
"users": {
"$uid": {
// grants write access to the owner of this user account whose uid must exactly match the key ($uid)
".write": "auth !== null && auth.uid === $uid",
// grants read access to any user who is logged in with Facebook
".read": "auth !== null && (auth.provider === 'facebook' || auth.provider === 'google')"
}
}
when I remove my rules all works ok.
My code is:
private createNewUser(user: any): any {
const newUser = this.af.database.object('users/' + user.uid);
newUser.set({
username: user.name,
email: user.email,
profile_picture: user.avatar,
provider : user.provider,
create_date: new Date().toISOString().slice(0, 10).replace(/-/g, "")})
}
what fileds do i need to check?
You have mistake in your rules.
You allow write access only for existing users who already has uid under users/uid node but it you do not allow write access on users node.
You need to allow write access under users node. But this will cascade, which means that none of the .write rules under users node will be checked if .write rule under users node will evaluate to true. So you need to change your existing .write to .validate.
"users": {
// Grant every logged in user to write here
".write": "auth !== null",
"$uid": {
// .validate rule will restrict .write if current user id does not match the key ($uid)
".validate": "auth !== null && auth.uid === $uid",
// grants read access to any user who is logged in with Facebook
".read": "auth !== null && (auth.provider === 'facebook' || auth.provider === 'google')"
}
}
For more information about how to setup your security rules, read the following link and watch the video on this link.
https://firebase.google.com/docs/database/security/
Finally I use this rules for users.
"users": {
"$uid": {
// grants write access to the owner of this user account whose uid must exactly match the key ($uid)
".write": "!data.exists() || auth.uid === $uid",
// grants read access to any user who is logged in with Facebook
".read": "auth !== null && (auth.provider === 'facebook' || auth.provider === 'google')"
}
}
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.
I'm looking for some advice or a possible solution with tightening up my firebase rules.
This is my user tree in Firebase:
users
|_male
|_uid
|_female
|_uid
The UID will be an epoch timestamp when the account is created which will be a signed integer.
These are the firebase rules which basically ensures the user has logged in and authenticated with Facebook before they can read or write to users:
"users": {
"male":{
".indexOn": ["uid"]
},
"female":{
".indexOn": ["uid"]
},
".read": "auth != null && auth.provider === 'facebook'",
".write": "auth != null && auth.provider === 'facebook'"
},
I only want users to read/write to their tree, for example:
users->male->uid->1233254...
I'm afraid with my rules above, they could potentially read and write from/to another users tree.
It would be great if I could compare the app UID with the Facebook UID.
I do capture this detail in another tree on the database e.g:
user_fbuid
|_fbuid
|_facebook:a1244dxs
|_uid
I do have better rules here that check against auth.uid:
"user_fbuid": {
"fbuid":{
"$fbuid": {
".indexOn": ["fbuid"],
".read": "$fbuid === auth.uid && auth.provider === 'facebook'",
".write": "$fbuid === auth.uid && auth.provider === 'facebook'"
}
},
},
If anyone has any ideas, I'd love to hear. Thanks
I ended up using the facebook id attribute as my own uid and the rules below:
"$uid": {
// only the user can read and write to their tree
".read": "auth != null && auth.provider === 'facebook' && auth.token.firebase.identities['facebook.com'][0] === $uid",
".write": "auth != null && auth.provider === 'facebook' && auth.token.firebase.identities['facebook.com'][0] === $uid"
},
Are these rules in correct format? When I put them in Database Rules, I see red dashed lines which may indicate an error/warning but when I hover over it, I receive no feedback.
{
"rules": {
"users": {
"$uid": {
// grants write access to the owner of this user account whose uid must exactly match the key ($uid)
".write": "auth !== null && auth.uid === $uid",
// grants read access to any user who is logged in --&& auth.provider === 'password'
".read": "auth !== null"
}
},
"usernames": {
"$userName": {
// grants write access to the owner of this user account whose uid must exactly match the key ($uid)
".write": "root.child('usernames').child($userName).child('uid').val() == auth.uid || root.child('usernames').child($userName).child('uid').val() == null",
// grants read access to any user who is logged in --&& auth.provider === 'password'
".read": "auth !== null"
}
},
"following": {
"$uid": {
// grants write access to the owner of this user account whose uid must exactly match the key ($uid)
".write": "auth !== null && auth.uid === $uid",
// grants read access to any user who is logged in --&& auth.provider === 'password'
".read": "auth !== null"
}
},
"followedBy": {
"$fid": {
"$uid": {
// grants write access to the owner of this user account whose uid must exactly match the key ($uid)
".write": "auth !== null && auth.uid === $uid",
// grants read access to any user who is logged in --&& auth.provider === 'password'
".read": "auth !== null"
}
}
}
}
}
This is what I see:
To reformat your code rules and make it read able
Just copy your rules and then go to JS cleaner and click claen Js re copy and past into your database rules
I've seen those too. Pretty much as soon as I add an empty line.
I think the empty lines are just causing a false error indicator to show up.
Since nothing's failing (at least not for me as far as I can see), I wouldn't worry about them.
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.
Before in my app I was creating accounts successfully until I put some rules
{
"rules": {
"users": {
"$uid": {
// grants write access to the owner of this user
// account whose uid must exactly match the key ($uid)
".write": "auth !== null && auth.uid === $uid",
// grants read access to any user who is logged in
// with an email and password
".read": "auth !== null && auth.provider === 'password'"
}
}
}
}
then, the accounts are created because I see those accounts in the dashboard. But once I try to create, I am getting this kind of errors
FIREBASE WARNING: set at /users/simplelogin:32 failed: permission_denied
Since you want the user to be able to create their own node initially, you'll need to explicitly allow the case where the location is new.
Based on the documentation on the auth parameter:
".write": "!data.exists() || auth.uid === $uid""
Note: I'm not entirely sure this will work, but felt it'd be more readable as in answer-format than as a "try this" comment.