My Chat and Friends node are separate of course, so would it be possible to refer to the friend node when writing rules for my Chat.
my current chat rules are as follows:
"Chats": {
"$uid_1":{
"$uid_2":{
".read": "auth.uid == $uid_1 || auth.uid == $uid_2",
".write": "auth.uid == $uid_1 || auth.uid == $uid_2 "
}
}
},
Friends structure in database
- Friends
-uid1
-uid2
- username
-uid2
-uid1
- username
when users are no longer friends, how do I make sure that messages do not go through? I have rules inside my android application but was told that I should write it in the security rules too.
You can check data anywhere in the database, by starting from the root variable.
So if you want to only allow uid2 to write to uid1's messages if their UID is stored under uid1's friend list, you can check:
".write": "(auth.uid == $uid_1 || auth.uid == $uid_2)
&& root.child('Friends').child($uid_1).child($uid_2).exists()"
You can try out these rules:
{
"rules": {
"chats": {
"$uid": {
"$uid2": {
".read": "auth.uid === $uid || auth.uid === $uid2",
".write": "auth.uid === $uid && root.child('friends').child($uid).child($uid2).exists()"
}
}
}
}
}
This will still keep READ access for both the users but they cannot write new messages.
Though your db structure looks a bit difficult to store messages. chats -> uid 1 -> uid2 won't be same always I believe or at least it will be difficult for you to maintain the order like which user remains 1st and so.
Related
I am using firebase database in my app. I have set the rules to allow normal users to create new childs in the node but I found that it's refused.
this is the writing rules of the node :
".write":"auth.uid == \"DFhNb28506Y345CpJ3Ye7DQNn713\" || ((newData.exists() && !data.exists()) || auth.token.email == data.child(\"userEmail\").val())",
I think that newData.exists() && !data.exists() should allow users to write in the database but this doesn't happened
this is the rules of the users node :
"users":{
".write":"auth.uid == \"DFhNb28506Y345CpJ3Ye7DQNn713\" || ((newData.exists() && data.child(\"userEmail\").val() != null) || auth.token.email == data.child(\"userEmail\").val())",
".read": "auth != null"
}
The database strucutre is like that :
-users
-user1
-userName, userEmail ....
-user2
-userName, userEmail .....
when a new user sign up in the app he should be allowed to push his data in the database
this is the database structre :
Ok, I think you're creating extra validation steps that aren't needed.
First
With ".read": "auth != null" on your users root, each user is able to access other user's data, so we should address the access for each user individually.
Second
If you just want to allow users that are authenticated to write and read its own contents, you can remove these extra ((newData.exists() && !data.exists()) and auth.token.email == data.child(\"userEmail\").val()) steps.
Tip: this ((newData.exists() && !data.exists()) comparison means exactly: Write here if you're sending anything but there should be nothing written in this requested "path". You should reflect on the need of this, as I don't know your exact use cases.
Also, I would guess the hardcoded UID you're requesting is of an Admin you've created - I wouldn't recommend this, please read more about user roles on this answer.
To clarify, I think your rules structure should be something like this:
{
"rules": {
".write":"auth.uid == \"DFhNb28506Y345CpJ3Ye7DQNn713\",
".read": "auth.uid == \"DFhNb28506Y345CpJ3Ye7DQNn713\",
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
Here's my database structure:
Clients:
employee1emailaddress
employee2emailaddress
Employees:
employee1emailaddress
employee2emailaddress
allClients:
client1phonenumber
client2phonenumber
I want to make a security rule to limit the authenticated user to read and write from nodes associated to their email address
For example:
the employee who has the email address of employee1emailaddress can only read from and write to the nodes that has their email addresses as the key
How to make that possible ? and thanks in advance..
I would recommend not associating data with a user's email address. You should use their UID instead:
{
"rules": {
"$uid": {
".read": "auth !== null && auth.uid === $uid",
".write": "auth !== null && auth.uid === $uid"
}
}
}
This will only allow users to read and write from a directory in your database where the key is their UID.
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.
I'm working on a Firebase rule configuration to control read/write access to my database. I had more rules written originally, but I've pared things down during troubleshooting. Here is my current rule configuration:
{
"rules": {
"developers": {
"$dev": {
".write": "!data.exists() && auth != null",
".read": "auth.devBucket === $dev",
"$proj": {
".read": "auth.devBucket === $proj",
"shared": {
".write": "!data.exists() || (auth.devBucket === $dev && auth.projBucket === $proj)"
}
}
}
}
}
}
What I'm trying to do is allow users of the Firebase to create a $dev node, $proj node, and shared node as long as they don't already exist and the user is authenticated. Then, I want to allow a user to have free write access within the shared node as long as their auth token's devBucket matches the $dev node they're writing within and their auth token's projBucket matches the $proj node they're writing within. I'm using the Firebase custom auth system for Android and I've loaded my tokens with these devBucket and projBucket variables. Authentication is definitely working according the my logcat, but I'm definitely getting permission denied errors with my current rules. I've been pouring over the Firebase Rule documentation and questions here for days and I am still puzzled as to the nuances of how their rule system works.
According to the documentation rules carry through to lower levels of nesting in the JSON, I'm just having trouble understanding how I can write a rules that allows a node and it's children to be created once, but also allows any number of children to be written or overwritten under shared if you're properly authenticated.
Does anyone have any idea how I could write rules to accomplish what I'm trying to do?
EDIT: I think it's also worth mentioning that I'm getting permission denied errors when I try to point listeners to my nodes too.
I figured out a configuration that worked for me.
{
"rules": {
"developers": {
".write": "!data.exists() || auth != null",
".read": "auth != null",
"$dev": {
".write": "!data.exists() || (auth != null && auth.devBucket == $dev)",
".read": "auth != null && auth.devBucket == $dev",
"$proj": {
".write": "!data.exists() || (auth != null && auth.projBucket == $proj)",
".read": "auth != null && auth.projBucket == $proj"
}
}
}
}
}
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.