iOS - Firebase 安全规则或规则模拟器中是否出现写入被拒绝错误?

iOS -Is Write Denied Error In Firebase Security Rules Or In The Rules Simulator?

我的数据库结构是:

root
  |
  @-users
  |   |
  |   @-uid
  |      |
  |      @-registration
  |      |     |
  |      |     |-completed: true
  |      |
  |      @-sneakersPath//registered users post/write sneaker for sale to this path
  |            |
  |            |
  |            @-autoID//i.e. xyz123
  |                |-sneakercondition: "used"
  |                |-sneakername: "nike"
  |
  |
  @searchSnkPath//registered and anonymous users can search/read the sneakers for sale here
      |
      @-autoID//xyz123
          |-sneakercondition: "used"
          |-sneakername: "nike"

我正在开发一个 iOS 应用程序,只有登录用户才能使用,并且我使用 Firebase 作为我的后端。我正在使用 2 种 Firebase 登录方法:Email/Password 和匿名。我有一个带有 email/password 字段和一个匿名用户输入按钮的登录场景。

有两种情况:

  1. 用户使用 Email/Password 方法创建了一个帐户。他们必须填写电子邮件和密码字段。一旦他们这样做了,这个用户就会得到一个永久的 uid 并创建一个 registration path。在该注册路径中,我添加了 key/value 对 completed:true。从那时起,用户按下登录按钮进入应用程序(他们使用永久 uid 登录)。此用户可以 post(write) 出售运动鞋给 sneakersPath。他们还可以搜索(read)他们或其他用户post出售的运动鞋。

  2. 匿名用户使用该应用程序而无需使用 Anonymous 方法创建帐户,这是一个匿名按钮。他们按下匿名进入按钮,就可以进入该应用程序。一旦他们按下那个按钮,他们就会得到一个他们访问时唯一的临时 uid(他们使用临时 uid 登录)。因为这个用户是匿名的,所以这个用户唯一能做的就是搜索(read)第一个场景中的其他用户post出售的东西。一旦他们注销,如果他们匿名重新登录,他们会得到一个不同的临时 uid。

在这两种情况下,我 运行 检查 client side 以验证用户是作为注册用户登录还是匿名用户。基于这些检查,我可以阻止匿名用户 post 匿名购买运动鞋。一切正常。

尽管我 运行 在 iOS 方面进行检查,但我想在我的 Firebase 规则中进行一些额外的强制执行,以确保匿名用户不能 post 任何东西,并且我想 运行 检查 kvp completed:true 特别是:

root.child('users').child($uid).child('registration').child('completed').val() === true"

现在我的安全规则是:

{
  "rules": {
    "users": {
       "$uid": {
            ".read": "$uid === auth.uid && auth != null"
            ".write": "$uid === auth.uid && auth != null && root.child('users').child($uid).child('registration').child('completed').val() === true"   
   }   
  }
 }
}

当我转到 Firebase 规则模拟器并尝试写入时,我得到:

在下面的图片中,我已将 Authenticated 切换到右侧 "on",我得到的唯一选择是 Anonymous、Google、Facebook、Twitter 和 Custom。由于我使用的是 Email/Password 并且未列出,因此我选择了自定义。我也没有选中管理框,因为我不知道它的用途。

我是在 Json 安全规则中做错了什么,还是我错误地使用了规则模拟器?

问题是在 Firebase 数据库中,我必须添加与 Firebase 在模拟器中给我的完全相同的 foo uid 数据。

root
  |
  @-users
  |   |
  |   @-uid//this is another user's uid
  |   |  |
  |   |  @-registration
  |   |  |     |
  |   |  |     |-completed: true
  |   |  |
  |   |  @-sneakersPath
  |   |        |
  |   |        |
  |   |        @-autoID
  |   |            |-sneakercondition: "used"
  |   |            |-sneakername: "nike"
  |   |
  |   |
  |   @59c96197-7cf9-44d3-bfbc-8d4f3324461//this is the foo uid the simulator provided. It must be added in the db so it can read it
  |   |  |
  |   |  @-registration
  |   |  |     |
  |   |  |     |-completed: true
  |   |  |
  |   |  @-sneakersPath
  |   |        |
  |   |        |
  |   |        @-autoID//abc789
  |   |            |-sneakercondition: "new"
  |   |            |-sneakername: "reebok"
  |
  @searchSnkPath
      |
      @-autoID//xyz123
      |    |-sneakercondition: "used"
      |    |-sneakername: "nike"
      |
      |
      |
      @-autoID//abc789
          |-sneakercondition: "new"
          |-sneakername: "reebok"

这是模拟器提供的 foo path/uid 数据:

注意 foo uid 也在令牌负载中:

如果您要使用数据库中的真实数据在模拟器中进行测试,请确保删除模拟器提供的 foo path/uid 并将其替换为 path/uid在您的数据库中,否则您将不断收到模拟写入拒绝响应。

在令牌有效负载中,您可以保留 "provider" : "anonymous" 以与数据库中的真实数据一起使用,但请务必将 foo uid 替换为您使用的任何一个