如何限制对在实时数据库中的特定节点下声明的用户的写访问权限

时间:2018-05-26 12:44:17

标签: android firebase firebase-realtime-database firebase-authentication firebase-security-rules

我注意到我的应用中有些奇怪。首先,我注册。

enter image description here

然后进入欢迎屏幕。

enter image description here

为了验证我确实在firebase中注册了,我进入控制台。首先是身份验证

enter image description here

然后在数据库中,您会看到一个名为Users的节点(我在注册时声明为Users)。

enter image description here

但是我要说我不小心从db中删除了这个用户。用户仍然登录应用程序并尝试对文章发表评论。显然,会有回应,

E/CommentActivity: User AhtNY3bm7aQdPiJewf3PBN310732 is unexpectedly null

这来自这里。

User user = dataSnapshot.getValue(User.class);

                    // [START_EXCLUDE]
                    if (user == null) {
                        // User is null, error out
                        Log.e(TAG, "User " + userId + " is unexpectedly null");
                        Toast.makeText(CommentActivity.this,
                                "Error: could not fetch user.",
                                Toast.LENGTH_SHORT).show();
                    }

CommentActivity的整个代码是here

有没有办法避免这种错误?我的意思是一旦用户在firebase中注册,即使他被意外删除,他也可以发表评论。也许从这里使用任何setter / getter方法?

public class User {

public String username;
public String email;


public User() {
    // Default constructor required for calls to DataSnapshot.getValue(User.class)
}

public User(String username, String email) {
    this.username = username;
    this.email = email;
}

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

}

更新

我把这个规则

{
  "rules": {
  ".read": "auth != null",
  ".write": "auth != null"
},
{
  "rules": {
  "comments": {
  ".write": "auth != null && root.child('Users').hasChild(auth.uid)"
  ".read": "auth != null"
  }
 }
 }  
}

但是我收到语法错误。

1 个答案:

答案 0 :(得分:1)

“身份验证”面板中用户的存在与数据库中Users节点下的用户数据之间没有自动链接。因此,正如您在帖子中提到的那样,如果删除数据库中的user节点,他/她仍然可以进行身份​​验证。

因此,您必须使用专用的安全规则来保护您的数据库(将其视为整个身份验证/授权机制的授权部分)。

您应该编写此数据库安全规则,以便用户的UID必须存在于Users节点下,以允许他/她编写“注释”,如下所示:

{
  "rules": {
    "comments": {
      ".write": "auth != null && root.child('Users').hasChild(auth.uid)"
      ".read": ...
    }
  }
}

在这里,我们假设comments节点直接位于数据库根目录下。您可以根据自己的数据模型调整此规则(可能还包括此路径中的帖子UID)。

查看有关安全性的相应文档,here,特别是文档末尾的完整示例。