Firebase Real-time DB Security Rules - firebase-realtime-database

when users are banned from the room, I want to remove these users read & write permission on security rules. Btw: I added the user id into the room for the check this user is banned.
Security Rules;
{
"rules": {
"live": {
"rooms": {
"$room": {
".write": "!$room.child('auth.uid').exists()", // auth.uid from Fb Auth
".read": "!$room.child('auth.uid').exists()",
}
}
}
}
}
Real-time database data
{
"live" : {
"rooms" : {
"1245" : { // room id
"14Kq4sx2X07FbNhOVBxQcYM3TZ8X53" : -1, // banned user uid from Auth
"comments" : [ {
"comment" : "hello",
"date" : "2020-12-20 20:23:33",
"uid" : "14Kq4sx2X07FbNhOVBxQcYM3TZ8X53",
"username" : "name"
} ]
}
}
}
}
But these rules are not working, when I added auth id into the room but every user can read & write this room

You have quotes around 'auth.uid', which means the rules check for that literal string: 'auth.uid'. If you want to check agains the value of auth.uid you should not put it in quotes.
So:
".write": "!data.child(auth.uid).exists()",

Related

How can I write the rule for the Firebase data structure below?

I want to write a rule in Firebase to allow only the user to be able to write to the database when the disable is set to false.
The structure of my database is as follows:
{
"Users": {
"UID": {
"details": {
"random key generated by push": {
"disable": true,
},
}
To read a value from another node inside your security rules, you have to know the exact path to that node. So unless you know the value of "random key generated by push", there is no way to read that from the rules on one of the nodes above it.
This usually means that you should change your data structure to have the disable flag at a known location under the UID node. For example:
{
"Users": {
"UID": {
"disable": true,
"details": {
"random key generated by push": {
},
}
Now you can allow access to UID node like this:
{
"rules": {
"Users": {
"$uid": {
".read": "data.child('disable').val() === true"
}
}
}
}

Firebase your realtime database has insecure rules warning

I have a website that uses Firebase Realtime Database. It usually sends me e-mail about insecure rules warning. I searched about this here and Firebase Documantation, but when I write other rules, it gives me such error:
Error saving rules - Line 10: String can't contain ".", "#", "$", "/", "[", or "]"
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"some_path/${uid}": {
".read": true,
// or ".read": "auth.uid != null" for only authenticated users
".write": "request.auth.uid == uid"
} SHOWS ME ERROR IS HERE.
}
}
I am using this rules for now:
{
"rules": {
".read": true,
".write": false
}
}
here is one picture that I try one of other rules called Mixed public and private access.
I will be very glad if anyone can help me.
The syntax does not seem correct to refer to a child resource, check below syntax to achieve the desired effect
{
"rules": {
"some_path": {
"$uid": {
".write": "$uid === auth.uid"
}
}
}
}
https://firebase.google.com/docs/database/security

Firebase rules realtime database

I try to return to the user the list of his chat with a rule.
So I don't know the id of the conversations.
I have tried several methods but none of them work because you have to know the chat id.
Database :
{
"Chats" : {
"-MPnCVZSVi5C3QbHnXl3" : {
"messages" : [ {
"createdAt" : 1609324431814,
"text" : "Gggwdhj",
"user" : "3Oi1atf8l2P4Vgsb8tZOGxpUg7q2"
} ],
"name" : "toto",
"users" : {
"3Oi1atf8l2P4Vgsb8tZOGxpUg7q2" : true
}
}
}
}
Rules :
{
"rules": {
"Chats": {
".read": "data.child('users').hasChild(auth.uid)",
".write": "true"
}
}
}
Result :
But when I access from the react native application. Access to chats does not pass for an authenticated user(uid : 3Oi1atf8l2P4Vgsb8tZOGxpUg7q2)
*The read failed: Error: permission_denied at /Chats: Client doesn't have permission to access the desired data.
Rules :
{
"rules": {
"Chats": {
"$uid":{
".read": "data.child('users').hasChild(auth.uid)",
".write": "true"
}
}
}
}
Query :
firebase.database().ref('Chats')
.limitToLast(20)
.on('child_added', snapshot => {
callback(this.parse(snapshot))
}, function (errorObject) {
console.log("The read failed: " + errorObject);
});
If you want to apply a certain rule/set of rules to all child nodes, you can use a $ wildcard like this:
{
"rules": {
"Chats": {
"$chatId": {
".read": "data.child('users').hasChild(auth.uid)",
".write": "true"
}
}
}
}
For more on this, see the Firebase documentation on $ wildcard variables. In general I'd recommend reading the Firebase docs on security rules end-to-end as they're not that long, and a few hours spent there now will save you much more time down the line.

Understanding Basic Firebase Security Rules on Firebase

I am using Firebase Auth and read a lot of documentation on security rules, custom claims, cloud functions, but I've really gotten more confused.
Consider the following data structure
{
"company": {
"idCompany1": {"data": "Restricted to Company1s users"},
"idCompany2": {"data": "Restricted to Company2s users"}
},
"users": {
"idUser1": {
"companies": {
"idCompany1": true
}
},
"idUser2": {
"companies": {
"idCompany1": true,
"idCompany2": true
}
}
}
}
I would like to implement a simple rule in the Firebase Console (Firebase Security Rule) without modifying my Data Structure.
The Rule I would like to configure is: A user can only read or write information in the companies to which it belongs (users/$idUser/companies/$idCompany === true on path company/$idCompany)
At this moment I have only configured:
{
"rules": {
"company" : {
".read": "auth != null",
".write": "auth != null",
}
}
},
"users" : {
"$user_id" : {
".read": "auth != null",
".write": "auth.uid === $user_id"
}
}
How can I configure this Firebase security Rule in the Firebase Console?
It sounds like you're looking for:
{
"rules": {
"company" : {
"$companyid": {
".read": "root.child('users').child(auth.uid).child('companies').child($companyid).val() === true"
}
}
}
}
This will allow the user to read /company/$companyid for any company where it is listed in their profile.
Note: you won't be able to read /company itself, as rules are not filters.

How prevent username from duplicate signUp in Firebase? [duplicate]

This question already has answers here:
Firebase android : make username unique
(4 answers)
Closed 6 years ago.
I want to prevent duplicate username while signUp form what user entered. I have created email login like below, firtly createUser and then auth it setValue with user dictionary.
But I stack with Firebase security settings and how to check handle this situation.
REF_BASE.createUser(email, password: pwd, withValueCompletionBlock: { ..
REF_BASE.authUser(email, password: pwd, withCompletionBlock: { ..
REF_USERS.childByAppendingPath(uid).setValue(user)
This handling always response error.
REF_USERS.childByAppendingPath(uid).childByAppendingPath("username").setValue(user["username"]) { (error: NSError!, result: Firebase!) in
if error != nil {
print(error.localizedDescription)
}
else {
self.REF_USERS.childByAppendingPath(uid).setValue(user)
}
}
This is my security rules, How Can I fix everything to be prevented from duplicate user?
"users": {
".read": "auth !== null",
"$user": {
"username": {
".read": "auth !== null",
".write": "newData.val() === auth.uid && !data.exists()"
}
}
},
Update:
From Frank's answer, but I don't know what I need to do while signUp new user for swift in this situation.
app : {
users: {
"some-user-uid": {
email: "test#test.com"
username: "myname"
}
},
usernames: {
"myname": "some-user-uid"
}
}
Need I add same user uid at the same time for two different nodes? If someone explain it in Swift. It would be great.
"users": {
"$uid": {
".write": "auth !== null && auth.uid === $uid",
".read": "auth !== null && auth.provider === 'password'",
"username": {
".validate": "
!root.child('usernames').child(newData.val()).exists() ||
root.child('usernames').child(newData.val()).val() == $uid"
}
}
}
I couldn't add new user informations to usernames parent node. It's needed another security rules?
If you are trying to prevent duplicate Firebase usernames, that can be done right at the createUser stage.
Assume a dialog is presented to new user asking to create an account: this will get their desired userName and password.
Send that to createUser and if there's an error (because it already exists) notify them and ask for a different userName:
myRootRef.createUser(email, password: pw, withValueCompletionBlock: { error, result in
if error != nil {
self.errMsgField.stringValue = "email/username in use, try again"
} else {
let uid = result["uid"] as! String //the uid of the new user
print("user created as \(uid)")
self.authUserWithAuthData( email, password: pw ) //auth the user
}
})
After the user is created you would probably add their info the /users node as well.

Resources