Firebase:无法添加用户条目(`set` 权限被拒绝)

Firebase: Cannot add user entry (`set` permission denied)

我想确保可以(从客户端)创建新用户,但只有经过身份验证的用户才能读取或写入现有对象。

我有一个简单的规则集:

{
    "rules": {
        "users": {
          "$uid": {
              ".read": "auth != null && auth.uid === $uid",
              ".write": "!data.exists() || auth.uid === $uid"
          }
        }
    }
}

我正在调用 createUser,然后在回调中我试图向我自己的 users 对象添加一个条目:

const usersRef = ref.child('users');

const userEntry = {
    [userData.uid]: {
        created: new Date().getTime()
    }
};

usersRef.set(userEntry)

我本以为即使用户还没有登录,他们也应该有写权限,因为!data.exists()。但是我收到 PERMISSION_DENIED 错误。

如果我在 users 级别上设置 ".write": true 那么它会级联(并覆盖?)我的内部规则不是吗?

编辑:

即使在以下情况下也会失败:

"users": {
  "$uid": {
      ".read": true,
      ".write": true
  }
}

谢谢。

我想我最初误解了这个问题。在您当前的回调中,由于 set 的工作方式,您正试图覆盖整个用户级别。

你真的只想设置不存在的东西:

const userRef = ref.child('users').child(userData.uid);

const userEntry = {
        created: new Date().getTime()
    };

userRef.set(userEntry);

那么,我认为您现有的规则会起作用。

我认为这是一个令人困惑的问题,因为创建用户和写入数据库是完全不同的事情。所以我只会在我的应用程序中展示我是如何做到的。

  1. 第一步是creating the user
  2. 下一步log the user in因为创建不会自动登录用户(我在创建用户的回调函数中这样做)
  3. 最后一步是 writing the user data to firebase

我使用以下规则来确保每个用户只能在 firebase 中写入他自己的节点 (documentation):

{
  "rules": {
    "users": {
      "$user_id": {
        ".write": "$user_id === auth.uid"
      }
    }
  }
}

要记住的一件事是 set() 将替换该路径上的任何现有数据。因此,请确保使用用户的 uid 而不是用户节点。

最后我想指出您在问题中发布的规则中的一个巨大缺陷:

".write": "!data.exists() || auth.uid === $uid"

此规则规定,如果还没有任何数据或者您有正确的 uid,您可以写入。该语句的第一部分是问题所在,因为 ANYONE 可以在没有任何数据时写入该位置。另外因为 $uid 是一个 dynamic path 你可以在那里添加任何东西,比如:

"users": {
  "WoWIjustMadeThisUp": {
    "nice": "Some huge value making you go over your limit"
  }
}

如果您希望用户只写一个初始值,之后将无法编辑它,只需使用 validate rule to check if there is already data at that location