I have the following rules for my Firebase Realtime Database:
{
"rules": {
"users": {
"$user_id": {
".read": "auth !== null && auth.uid == $user_id",
".write": "auth !== null && auth.uid == $user_id",
".validate": "data.hasChildren(['calculations', 'daily', 'firstName', 'lastName', 'monthly', 'profileImageUrl', 'uid', 'username', 'weekly'])",
"calculations": {
".validate": "data.isNumber()",
},
"daily": {
".validate": "data.isNumber()",
},
"firstName": {
".validate": "data.isString()",
},
"lastName": {
".validate": "data.isString()",
},
"monthly": {
".validate": "data.isNumber()",
},
"profileImageUrl": {
".validate": "data.isString()",
},
"uid": {
".validate": "data.isString()",
},
"username": {
".validate": "data.isString()",
},
"weekly": {
".validate": "data.isNumber()",
},
"$other": {
".validate": false
}
}
}
}
}
Old Firebase Realtime Database Rules that worked for new users:
{
"rules": {
".read": "auth.uid == $user_id",
".write": "auth.uid == $user_id"
}
}
Firebase Authentication with email and password:
// Firebase Authentication to create a user with email and password
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
val user = auth.currentUser
// Send an email verification to the user. Only allow them to login after they
// have verified their email.
user!!.sendEmailVerification().addOnCompleteListener { task ->
if (task.isSuccessful) {
// Save username, first name, and last name on Firebase Database
val uid = auth.uid ?: ""
val ref = database.getReference("/users/$uid")
val newUser = User(uid, userName, firstName, lastName, 0.0, 0.0, 0.0, 3, "")
ref.setValue(newUser)
Toast.makeText(
this,
"Please check your inbox and verify your email address.",
Toast.LENGTH_LONG).show()
val intent = Intent(this, LoginActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK.or(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
}
}
}
// If sign in fails, display a message to the user.
.addOnFailureListener {
Toast.makeText(
baseContext, "Failed to create an account: ${it.message}",
Toast.LENGTH_LONG
).show()
}
User class:
@IgnoreExtraProperties
data class User(
val uid: String,
val username: String,
var firstName: String,
var lastName: String,
val daily: Double,
val weekly: Double,
val monthly: Double,
val calculations: Int,
val profileImageUrl: String
)
These rules work for existing users. But if I try to create a new user, these rules don't work. I can't create new data in my database for new users that have signed up. How do I fix this?
uid
right after you get it withval uid = auth.uid ?: ""
what is the output? Also: this is one of those cases where using a?:
operator is actually hurting you. Your code assumeduid
is not empty, so you should not convertnull
to""
there but instead fail ifuid
is stillnull.
– Frank van Puffelenuid
is the new user's ID.uid
is not empty and this code worked before the changes to my database rules. I changed the rules to enhance security but if I revert back to my less secure rules, the rules don't work for new users who just signed up. – Tom Darious