Firebase database rules for a collection shared with two users - firebase

I have this collection
"connection-requests":{
"push-key1":{
"foo":"bar",
"biz":"baz",
"user1":{
"some-info":"",
"uid":"user1uid"
},
"user2":{
"some-info":"",
"uid":"user2uid"
}
}
}
I want this collection to be readable and writable only by the two users whose uid is present this collection.
This is my database rules:
"connection-requests": {
"$key": {
".read": "root.child('connection-requests').child($key).child('user1/uid').val() == auth.uid || root.child('connection-requests').child($key).child('user2/uid').val() == auth.uid",
".write": "root.child('connection-requests').child($key).child('user1/uid').val() == auth.uid || root.child('connection-requests').child($key).child('user2/uid').val() == auth.uid",
}
}
Im accessing the data using this request :
db.ref('connection-requests')
.orderByChild('user1/uid')
.equalTo(uid) // <- auth.uid of user
.once('value')
.then()
.catch()
The rules above doesn't work, my guess is that there is something wrong with .child($any) part but Im not sure what.
Thanks in advance.

The closing double-quote for each rule is misplaced. Instead of being at the end of the line, it is following the OR operator:
auth.uid || "root.child
^
^
Should be:
"connection-requests": {
"$key": {
".read": "root.child('connection-requests') ... == auth.uid",
".write": "root.child('connection-requests') ... == auth.uid",
}
}

Related

firebase realtime database rules to allow multiple uid for write access

I need to allow only 2 specific uid for write access and I can't publish with my current rule:
{
"rules": {
".read": "auth != null",
".write": "auth != null && auth.uid === 'abc123' || '123abc'",
}
}
It keeps complain "rule regulation may not contain '|' operator" and
"right operand for '||' must be boolean", which ever i used.
How should I change my rule to achieve what I want?
Any help will be much appreciated.
The word after || is actually not a boolean, it is just a string. Please, check my fixed code.
{
"rules": {
".read": "auth != null",
".write": "auth != null && (auth.uid === 'abc123' || auth.uid === '123abc')",
}
}

Firebase Realtime database rules "Unknown variable 'request'."

Does anyone know why I can't use this snippet from here https://firebase.google.com/docs/rules/basics#realtime-database_2
It looks like a documentation mistake because in Firestore you would write request.auth.uid while in the RTDB you just write auth.uid.
{
"rules": {
"some_path": {
"$uid": {
// Allow only authenticated content owners access to their data
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
}

Firebase remove child permission denied

The JSON looks like this:
I want to remove the child which is [steven : uid] from user_lookup
This is the code:
self.ref.child("user_lookup").queryOrderedByValue().queryEqual(toValue: user?.uid).observe(.value, with: { snapshot in
if snapshot.exists() {
print("I got it")
// remove [steven, uid]
} else {
print("Not found")
}
I don't know how to remove the child, but i've tried to type removeValue but i got Permission_denied
Here is the rules:
`"user_lookup": {
".read": "auth !== null",
".write": "auth !== null && !data.exists()",
".indexOn": [".value"],
I think its because "!data.exists()" but I don't want to duplicate data, so how to fix that?
And how can i remove the child, Any help will be appreciated.
I think this might be what you want:
".write": "
(auth.uid === newData.val() && !data.exists()) ||
(auth.uid === data.val() && !newData.exists()"
The first expressions or the or allows user to claim their name if it doesn't exist yet. The second expression allows then to delete their claim.

Security rules in Firebase

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.

Firebase data structure and security rules

Im having trouble with the security rules for firebase and Im not 100% where I am going wrong. I am thinking that maybe I have my data structure wrong:
{
"users": {
"uid": {
"displayName": "Name";
}
},
"modules": {
"id": {
"title": "buttons",
"uid": "(user id string)"
},
"id": {
"title": "navbars",
"uid": "(user id string)"
}
},
"snippets": {
"id = moduleID": {
"id (of snippet)": "(id string)" {
"uid (user ID)": "(string)",
"body": {
"css": "(some code)",
"html": "(Some code)",
"name": "(string)",
"description": "(string)"
}
}
}
}
Everything in the app works fine, but when I started to add security rules I got access denied errors. Im just wondering if I have the data structure correct in the first place or is the security rules completely wrong?
Security rules:
{
"rules": {
"users": {
"$uid": {
// grants write and read access to the owner of this user account whose uid must exactly match the key ($uid)
".write": "auth != null && auth.uid == $uid",
".read": "auth != null && auth.uid == $uid"
}
},
"snippets": {
"$uid": {
// grants write and read access to the owner of this user account whose uid must exactly match the key ($uid)
".write": "auth != null && auth.uid == $uid",
".read": "auth != null && auth.uid == $uid"
}
},
"modules": {
"$uid": {
// grants write and read access to the owner of this user account whose uid must exactly match the key ($uid)
".write": "auth != null && auth.uid == $uid",
".read": "auth != null && auth.uid == $uid"
}
}
}
Any advice would be greatly appreciated.
It seems the rules are malformed based on the data structure.
The rules have $uid's in each node but your data doesn't match that. Users has uid but modules has id and snippets has id = moduleID.
$uid is a variable that holds the node name so it can be referenced inside { } so you should (for readability) rename that variable in the other two nodes to something that makes more sense inside each {}. Like in modules, have it $module_id.
However. I think the jest of this is you want to limit reading snippets and modules to authenticated users. To do that, you can reference the users node.
a .read rule would be something like this
"modules": {
"$module_id": {
".read": "auth != null && root.child('users/' + auth.id).exists()
}
So your modules node can be read by a user that is auth'd and their uid also appears in the users/ node
Are you using the Firebase Bolt compiler for rules? I had to write some complex rules and doing it by hand gets confusing very quickly.
Below is what it would looks like. Very easy to make changes, compile and try them out.
//current logged in user
isUser(uid) = auth != null && auth.uid == uid;
//does this module id exist
hasValidModule(module_id) = root['modules'][module_id] != null;
//dont let anyone read or write to top node
path / {
read() = false;
write() = false;
}
path /users/$user_id
{
write() = isUser($user_id);
read() = isUser($user_id);
}
path /snippets/$module_id/$snipit_id/$user_id
{
write() = isUser($user_id) && hasValidModule($module_id);
read() = isUser($user_id);
}
path /modules/$user_id
{
write() = isUser($user_id);
read() = isUser($user_id);
}
Here's the json it spits out:
{
"rules": {
"users": {
"$user_id": {
".read": "auth != null && auth.uid == $user_id",
".write": "auth != null && auth.uid == $user_id"
}
},
"snippets": {
"$module_id": {
"$snipit_id": {
"$user_id": {
".read": "auth != null && auth.uid == $user_id",
".write": "auth != null && auth.uid == $user_id && newData.parent().parent().parent().parent().child('modules').child($module_id).val() != null"
}
}
}
},
"modules": {
"$user_id": {
".read": "auth != null && auth.uid == $user_id",
".write": "auth != null && auth.uid == $user_id"
}
}
}
}
There's some info on the Firebase blog but the doc that really helped me is this
https://github.com/firebase/bolt/blob/master/docs/language.md

Resources