首页 > 解决方案 > 如何限制对实时数据库中特定节点下声明的用户的写访问

问题描述

我在我的应用程序中发现了一些奇怪的东西。首先,我注册。

在此处输入图像描述

然后进入欢迎屏幕。

在此处输入图像描述

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

在此处输入图像描述

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

在此处输入图像描述

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

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 的完整代码在这里

有没有办法避免这种错误?我的意思是一旦用户在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"
  }
 }
 }  
}

但我得到一个语法错误。

标签: androidfirebasefirebase-realtime-databasefirebase-authenticationfirebase-security

解决方案


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

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

您应该以这样一种方式编写此数据库安全规则,即用户的 UID 必须存在于Users节点下,以允许他/她编写“评论”,如下所示:

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

在这里,我们假设该comments节点直接位于数据库根目录下。您可以根据您的数据模型调整此规则(并且可能在此路径中包含 post UID)。

在此处查看有关安全性的相应文档,尤其是文档末尾的完整示例。


推荐阅读