在我使用Firebase创建的iOS应用中,每个用户都有一个唯一的用户名,该用户名是在用电子邮件和密码注册后创建的。
因此,如果有电子邮件test5@gmail.com的用户已注册,然后必须创建一个不在用户名数据库中的唯一用户名,则数据库的片段如下:
"usernames" : {
"test" : "r6KPesUr1qORfIJke07SloZHeNW2",
"test1" : "jSMSkY9rHtdNkXoLrsFmCAXdY9n2",
"test7" : "jnFhJbgCjZeJFx0hspObqoskQej2",
"test8" : "HtnULzU0lnZKYva2M2Wepl6N8wE3"
},
"users" : {
"HtnULzU0lnZKYva2M2Wepl6N8wE3" : {
"email" : "test8@gmail.com",
"username" : "test8"
},
"boX6rtJ98haWVxNoXfSq21maCVU2" : {
"email" : "test5@gmail.com"
},
"jSMSkY9rHtdNkXoLrsFmCAXdY9n2" : {
"email" : "Test1@gmail.com",
"username" : "test1"
},
"jnFhJbgCjZeJFx0hspObqoskQej2" : {
"email" : "test7@gmail.com",
"username" : "test7"
},
"r6KPesUr1qORfIJke07SloZHeNW2" : {
"email" : "test6@gmail.com",
"username" : "test"
}
}
我有以下安全规则,以确保用户完成注册时用户名是唯一的。
// USERNAMES
"usernames": {
".read": "auth.uid != null",
".write": "auth.uid != null",
"$username": {
".validate": "(!root.child('usernames').hasChild($username.toLowerCase()) && newData.val() == auth.uid &&
root.child('users').hasChild(auth.uid)) &&
(root.child('users/'+auth.uid+'/username').val().toLowerCase() == $username ||
!root.child('users/'+auth.uid+'/username').exists())"
}
}
对于验证规则,我希望这三个语句必须具有
(!root.child('usernames').hasChild($username.toLowerCase()) &&
newData.val() == auth.uid &&
root.child('users').hasChild(auth.uid))
并且有了这两个陈述,其中一个必须是真的
"(root.child('users/'+auth.uid+'/username').val().toLowerCase() == $username ||
(!root.child('users/'+auth.uid+'/username').exists()"
因此,如果用户希望使用以下json注册 test5 作为用户名,那么由于OR语句的第一部分,它将无法使用我当前的安全规则。
"users": {
"boX6rtJ98haWVxNoXfSq21maCVU2": {
"username": "test5"
}
}
我做错了什么?
答案 0 :(得分:1)
似乎您希望用户声明用户名有两件事:
/users/$uid/username
下,用户名为/usernames/$username
下使用UID 您现在编写的JSON代码段仅包含#1。它不包含在/usernames
下编写用户名的任何内容。因此规则将拒绝它,因为您正在验证用户名必须存在并为该用户声明。
您可能希望验证#1和#2同时发生,这将是一个多位置更新,如:
"users/boX6rtJ98haWVxNoXfSq21maCVU2/username": "test5",
"usernames/test5": "boX6rtJ98haWVxNoXfSq21maCVU2"
您的规则是:
"usernames": {
"$username": {
".validate": "!data.exists() &&
newData.exists() &&
newData.parent().parent().child('users').child(auth.uid).child('username').val() === $username"
}
}
"users": {
"$uid": {
"username": {
".validate": "!data.exists() &&
newData.exists() &&
newData.parent().parent().parent().child('usernames').child(newData.val()).val() === $uid"
}
}
}
我删除了有关小写的内容,因为在代码中更容易修复它并且只存储小写用户名。