My database has a users
child with fields email
and name
, with the key being the users uid. Here are the database rules:
{
"rules": {
"users": {
"$uid": {
"email": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
},
"name": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
}
}
}
}
}
I am using pyrebase to access the firebase project. Here is the statement that tries to add them to users
:
db.child("users").child(self.user["localId"]).set({"name": name, "email" : email})
While creating a new user, I get a permission denied error. The user is still able to sign in though. When I make a simulated request with the rules playground, it succeeds.
edit: Here is a reproducible example:
import pyrebase
config = {
"apiKey": "",
"authDomain": "",
"projectId": "",
"databaseURL": "",
"storageBucket": "",
"messagingSenderId": "",
"appId": "",
"measurementId": "",
}
firebase = pyrebase.initialize_app(config)
user = firebase.auth().sign_in_with_email_and_password("[email protected]", "password")
db = firebase.database()
db.child("users").child(user["localId"]).set({"name": "test", "email": "[email protected]"}, token=user["localId"])
2
Answers
If you want the user to be write their own
name
andemail
, but no other properties, the more idiomatic way to do that would be:So we authorize writing for the entire
/users/$uid
node here only once, and then determine what individual child properties are valid under there, and disallow all other properties.The user ID (
user["localId"]
) shouldn’t be passed in as the authentication token. You need to pass the user’s ID token instead (user["idToken"]
). So while you may be writing to the correct location, you are doing so without providing the right authorization.