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
Related
This is what my rules look like:
{
"rules": {
"users": {
"$uid": {
".write": "$uid === auth.uid",
".read": "$uid === auth.uid"
}
},
"classes": {
"$classid": {
".read": "root.child('users').child(auth.uid).child('memberOfClasses').child('val').val().matches(*$classid*) || root.child('users').child($uid).child('ownedClasses').child('val').val().matches(*$classid*)",
".write": "root.child('users').child(auth.uid).child('memberOfClasses').child('val').val().matches(*$classid*) || root.child('users').child($uid).child('ownedClasses').child('val').val().matches(*$classid*)"
}
}
}
}
I'm getting Simulation failed - Line 11: syntax error (line 11 is the classes/$classid.read). I'm guessing it has something to do with the regex in .matches(*$classid*)
I'm trying to get it so that if for example users/auth.uid/memberOfClasses or ownedClasses equals something like "154 321 ABC", I would be able to access classes/154, classes/321, and classes/ABC.
What am I doing wrong?
The value that you pass in to matches must be a string literal.
This might work: .matches("*"+$classid+"*")
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.
EDIT: this will also not work if I will set ".read": "true"
in any child or any sub-tree including the rules root (this is not showing here in the examples).
In my app, which manage user's wedding details such as guests, I want to let the guests write to the "arrive" field only if the "invited" field is exists (actually if it will be true , but I checked if it exists just for testing). However, I didn't manage to do this since in the Firebase console it's says that the simulated set is denied :
The rules in the Firebase console:
{
"rules": {
"Users": {
"$uid":{
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
},
".indexOn": "email"
},
"Guests":{
"$uid":{
"$guest_id":{
"arrive":{
".read": "$uid === auth.uid",
".write": "root.child('Guests/'+ $uid + '/' + $guest_id +'/invited').exists()"
}
}
}
}
}
}
The JSON example I wrote in the Rules Playground in the console:
{
"Guests": {
"user_1": {
"guest_1": {
"arrive": false,
"invited": true
}
}
}
}
The location path in the Rules Playground:
/Guests/user_1/guest_1/arrive
I tried several approaches and they didn't work. For example:
".write": "data.parent().child('invited').exists()"
or
".write": "root.child('Guests').child($uid).child($guest_id).child('invited').exists()"
This is my node Jason:
{
"Users' Input History" : {
"TdtIwvAPewRr1l9HY67PfkLBPbn2" : {
"-M-eylUaQcCpoyTLwbhk" : "fate"
}
},
"Users' Vocabulary List" : {
"TdtIwvAPewRr1l9HY67PfkLBPbn2" : {
"-M-eyxRLoCpDftWQ4cDn" : "hardliner"
}
}
}
This "TdtIwvAPewRr1l9HY67PfkLBPbn2" is the uid for a user who can read and write his own value (here, it is "fate") under the "Users' Input History" node, and value (here, it is "hardliner") under the "Users' Vocabulary List" node.
This Jason will go on and on to have multiple users (uids) and their own multiple values. Each new user (uid) will populate under both the "Users' Input History" node and the "Users' Vocabulary List" node, and new values from that new user will populate under the new uid.
For example, I want user A (uid A) to able to read and write only his own values, and cannot read and write values from other users (uid B, C, D and so on), so I wrote my database rule like so:
{
"rules": {
"Users' Input History": {
"$uid": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
}
}
},
"Users' Vocabulary List": {
"$uid": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
}
}
}
However, as in the image below, I'm getting this error saying Simulation failed at line 12: Expected '}'. Note that there's a red mark on line 12 and a ^ mark on line 13.
What I tried:
I added '}' right before "Users' Vocabulary List". That didn't work and then I added right before "$uid". Both led me to the same error message saying: Parse error. I don't know what else I can try. Is my rule wrong and how can I correct it?
Your nested child for "Users' Vocabulary List" looks to be in the wrong place. Move it up inside the "rules" object.
{
"rules": {
"Users' Input History": {
"$uid": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
}
},
"Users' Vocabulary List": {
"$uid": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
}
}
}
}
I have my rules for the index, but I am still getting this following error when data is large.
The Error is #firebase/database: FIREBASE WARNING: Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding ".indexOn": "time" at /history/bearhistory to your security rules for better performance.
"rules": {
".read": true,
".write": true,
"bearhistory": {
".indexOn": ["time"]
},
"history": {
".indexOn": ["time"]
}
}
}
As I said, it works when I work with minimum limitToLast.
this.items = this.db.list(`history/bearhistory`, ref => ref.orderByChild("time").limitToLast(10000));
When data limitToLast is bigger, I am getting these error for the index. I have this data structure.
How can I fix the error to work on the index?
As the error message says, the query is running on /history/bearhistory, so that is where you need to define the index:
"rules": {
".read": true,
".write": true,
"history": {
".indexOn": ["time"],
"bearhistory": {
".indexOn": ["time"]
}
}
}