我在这里如何解决我的应用程序的安全问题。
我有这个结构:
用户不应该写入积分,但能够写入昵称。 这可能吗?
我尝试了这条规则,但它不起作用
"Users" :{
"$user_id" :{
"Points" :{
".read" : true,
".write" : false
},
"nickname" :{
".read": true,
".write": "$user_id==auth.uid"
}
更新
将数据拆分为两个节点是问题的一部分的解决方案,留下编写昵称的问题的另一部分。 只有昵称所属的用户才能编写昵称,但在我的代码中,我要求用户输入电子邮件,密码和昵称。 当用户是registring时,auth.uid还不可用,我考虑在临时名称下注册用户,并且他们在登录后稍后更改它,但我正在寻找一个更短的解决方案,他们可以在注册时选择名称
这是他们注册时的一些代码:
Ref.createUser(email, pass,
new Firebase.ValueResultHandler<Map<String, Object>>() {
@Override
public void onSuccess(Map<String, Object> result) {
Ref2 = new Firebase(firebase_users_path + result.get("uid").toString());
HashMap<String, String> names = new HashMap<String, String>();
names.put("nickname", nickname);
Ref2.setValue(names, new Firebase.CompletionListener() {
@Override
public void onComplete(FirebaseError firebaseError, Firebase firebase) {
if (firebaseError != null) {
Toast.makeText(MainActivity.this, "Done!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Error!", Toast.LENGTH_SHORT).show();
}
}
});
我的代码正在返回完成!指示注册完成后,我确实找到了一个新用户,但昵称没有写入users / uid,因为auth.uid尚未可用
答案 0 :(得分:3)
一个广泛的猜测(因为失败的代码丢失)是你正在尝试写一个用户记录:
ref.child('Users').child(auth.uid).set({ 'nickname': 'masood' });
此操作将失败,因为用户没有对用户节点的写访问权。
出于这个原因(以及其他一些人),最好将数据拆分为用户具有不同访问类型的单独节点。在你的情况下:
User_names
0a88b...
nickname: "First_user"
User_scores
0a88b...
Points: 35
现在,您可以轻松地将其保护和更高一级:
"User_names" :{
"$user_id" :{
"nickname" :{
".read": true,
".write": "$user_id==auth.uid"
}
}
},
"User_points" :{
"$user_id" :{
"Points" :{
".read" : true,
".write" : false
}
}
}
您甚至可能希望将.read
提升到更高级别,以便任何人都可以列出用户名和分数:
"User_names" :{
".read": true,
"$user_id" :{
"nickname" :{
".write": "$user_id==auth.uid"
}
}
},
"User_points" :{
".read" : true,
"$user_id" :{
"Points" :{
".write" : false
}
}
}
Firebase docs on how rules cannot be used to filter data中有一个相当不错的部分。