JSON looks like this:
"messages" : {
"msg" : {
"-Kr2Qb93tM7yP-J7zuAq" : {
"text" : "hello",
"toId" : "EeLIxkOEfhMUlsM8WGnHdgeT8xW2",
"fromId" : "IxfnlsekOh8WEG2HdgMUMWT8xEeL"
}
}
}
How can i only give read permission for "-Kr2Qb93tM7yP-J7zuAq" to user if "toId" 's value contain his uid?
And "fromId" can Edit\delete the snapshot.
Thanks!
Change your Firebase Realtime Database Rules to the following :-
rules": {
.
.
"messages" : {
"msg" : {
"$messageID" :{
".read" : "data.child('toId').val() == auth.uid",
".write": "data.child('fromId').val() == auth.uid"
}
}
}
}
Also, what you're asking is pretty basic. So, I would really recommend you to read up on Firebase Rules here.
Related
I'm creating an application which lets users create items and then allow other users to subscribe to those items. I'm struggling to craft a rule that will prevent users from subscribing more than once to an item.
Here is an example of my data structure (anonymized, hence the "OMITTED" values):
{
"OMITTED" : {
"name" : "Second",
"body" : "this is another",
"userName" : "Some User",
"userId" : "OMITTED",
"created" : 1385602708464,
"subscribers" : {
"OMITTED" : {
"userName" : "Some User",
"userId" : "OMITTED"
}
}
}
}
Here are my Firebase rules at present:
{
"rules": {
".read": true,
".write": "auth != null",
"items": {
"$item": {
".write": "!data.exists()",
".validate": "newData.hasChildren(['name', 'body', 'userId', 'userName']) && newData.child('userId').val() == auth.id",
"subscribers": {
"$sub": {
".validate": "newData.hasChildren(['userId', 'userName']) && newData.child('userId').val() != data.child('userId').val()"
}
}
}
}
}
}
How can I prevent users from subscribing more than once? What is the rule I need to prevent duplicate users within the subscribers list based on userId?
Since security rules can't iterate a list of records to find the one containing a certain bit of data, the trick here is to store the records by an ID which allows for easy access. There is a great article on denormalization which offers some good insights into this practice.
In this case, if your use case allows, you may simply want to switch your data structure so that records are stored by the user's id, rather than storing the ID as a value in the record, like so:
/users/user_id/items/item_id/subscribers/user_id/
In fact, as you'll see in denormalization, you may even benefit from splitting things out even farther, depending on the exact size of your data and how you'll be reading it later:
/users/user_id
/items/user_id/item_id
/subscribers/item_id/user_id
In either of these formats, you can now prevent duplicates and lock down security rather nicely with something like this:
{
"users": {
"$user_id": { ".write": "auth.id === $user_id" }
},
"subscribers": {
"$subscriber_id": { ".write": "auth.id === $subscriber_id" }
}
}
How can I add new rule to Firebase Realtime Database so that users can read data where recid equal to user ID?
I have a massage table with this structure:
"messages" : {
"-KyyjeMOtc7fWAsOiuiP" : {
"recid" : "FL5hyQJrsHWRQsRtiLe1PxkyRnk1",
"senderid" : "6K6pQHaCishDlCb0Y9AaN3zI22n1",
"text" : "hi"
},
"-KyykczCNpsSL6a1t8vt" : {
"recid" : "FL5hyQJrsHWRQsRtiLe1PxkyRnk1",
"senderid" : "6K6pQHaCishDlCb0Y9AaN3zI22n1",
"text" : "test"
},
}
I want a rule that when data is added to the database, only the user whose uid is equal to recid can see the data.
To achieve this, you can create user-based security rules for your database, something similar to:
{
"rules": {
"messages": {
"$messageId": {
".read": "auth.uid == data.child('recid').val()",
".write": "auth !== null"
}
}
}
}
In this example, $messageId uses a $location variable that will match any key under your messages list. Then, we grant read access only if the current user's auth.uid matches the recid child value.
I'm really scratching my head here, and I've been reading as much as I can on many other cases. I'm new to Firebase, but got some understanding of it. I was wanting to restrict certain records of the database to certain users. So here's my JSON:
"accounts" : {
"13asdf313" : {
"dog" : "bacon",
"email" : "luis#fakeemail.com",
"first" : "luis",
"last" : "xxxx"
},
"HlELrrGDbiMKgxxxx" : {
"name" : "Luis"
},
"anthony" : {
"email" : "anthony#fakeemail.com",
"last" : "xxxx",
"name" : "anthony"
},
"jpSq6UzX0mcAvExxxx" : {
"name" : "anthony"
}
}
Here are the rules set up based on what I've been reading:
{
"rules": {
"accounts":{
"$uid":{
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
}
},
}
}
In the simulator, I used the bottom condition (I even put /accounts in the location field). I used the UID: HlELrrGDbiMKgxxxx, copied straight from Firebase account list.
This is always coming up as failed
What am I doing wrong?
You have to insert accounts/HlELrrGDbiMKgxxxx into the Location field.
Otherwise you are trying to access the whole database (standard location is root, which covers the whole database). Your rule is just set for the child accounts/$uid and to access it the user id from authentication and the child location in the database must match.
I am new to Firebase, and I was trying to setup security rules where I want users to be grouped by dynamically created groups. I also want the user to be able to read all content from the same group, but not other groups.
When I create new users and assign them some groups using push, I get data like the following:
{
"groups" : {
"default" : {
"-Jtcdyniz1yVwNQCGSAR" : {
"user" : "simplelogin:5"
},
"-Jtd114KNQ-rqh6-rlnI" : {
"user" : "simplelogin:7"
}
}
},
"users" : {
"simplelogin:5" : {
"group" : "default",
"name" : "123"
},
"simplelogin:6" : {
"group" : "default1",
"name" : "1"
},
"simplelogin:7" : {
"group" : "default",
"name" : "23"
}
}
}
Can anyone help here? How can I setup authentication rules? I have tried with following but it doesn't seem to work...
{
"rules": {
"users" : {
"$userid" : {
".read" : "data.child('users').child($userid).child('group').val() === data.child('users').child(auth.id).child('group').val()",
".write" : "$userid === auth.uid"
}
}
}
}
I assume that this should be fairly simple use-case but unfortunately didn't get much help.
Whatever posts that I found had direct users inside a group instead of a subchild of a random, unique string.
EDITED:
I tried with edited rules like :
{
"rules": {
"groups" : {
".read" : "true",
".write" : "true"
},
"users" : {
"$userid" : {
".read" : "data.child('group').val() === root.child('users').child(auth.id).child('group').val()",
".write" : "$userid === auth.uid"
}
}
}
}
but I did not get much help.
For code, I have added it as a fiddler at : http://jsfiddle.net/digish_gabhawala/ytwmokg0/
What I want at the moment is two simple things:
1> as a user, I should be able to edit my name
2> when I click button, I should be able to get names of all users in my group.
When I tried the code as in fiddler, I am getting permission issues.
It would be great if I can get what is it that I am doing wrong.
I'm pretty sure that the issue is that you're using $userid instead of $uid. So changing this should make it work. I'm using $uid in my security rules.
I have a data structure that adds user's data to their unique id such as follows.
"users" :
{
"user_id":
{
"name":"John Doe",
"email":"email#example.com",
"account":"limited",
"avatar" : "this will be a base64 data string"
}
}
I want to deny users from listing other users and I also want logged in users to access their data based on their "user_id" which is gotten from auth.uid
I had tried some rules:
{
"rules" :
{
"users" :
{
".read" : "false",
".write" : "auth != null && !data.exists() && newData.exists() ",
".validate" : "newData.child('user_id').hasChildren(['name', 'email', 'account','avatar'])",
"user_id" :
{
".read" : "auth.uid === user_id",
".write" : "false",
"avatar" :
{
".write" : "!data.exists() && newData.exists() && auth.uid === user_id",
".read" : "auth.uid === user_id"
}
}
}
}
}
Now keeping in mind that "user_id" can be anything and it changes per user, how can I implement that? Do you have other suggestions on a way I can work this out?
You need to take a close look at the Firebase documentation found here: https://www.firebase.com/docs/security/guide/user-security.html
You need to make use of the wildcard path to represent each user like this:
{
"rules": {
"users": {
"$user_id": { //this is the WILDCARD path
// grants write access to the owner of this user account
// whose uid must exactly match the key ($user_id)
".write": "$user_id === auth.uid"
}
}
}
}
Wildcard paths explanation: https://www.firebase.com/docs/security/api/rule/path.html
Finally, I wouldn't recommend storing the email in this way because it will be available anyway via simpleLogin.