【问题标题】:Firebase Security - How to allow to push to a node AND update subtree on that node?Firebase Security - 如何允许推送到节点并更新该节点上的子树?
【发布时间】:2017-07-04 14:55:27
【问题描述】:

我觉得这是一个很常见的问题,但由于我一直在学习 Firebase 安全性,我似乎仍然无法解决这个小问题,因为我有一个树节点,我希望能够将新数据推送到,同时能够更新现有节点。根据 Firebase 文档,如果您将这些规则放在顶层树中,您应该能够创建/删除,但不能更新:

".write": "!data.exists() || !newData.exists()"

因此,当我使用 Firebase 数据库模拟器进行身份验证和所有操作时,我会在路径 /social/bands 上模拟“写入”,但是我得到了 Simulated write denied。我应该注意到,在这条路径中,数据确实存在。

我对这个例子的完整规则如下:

"social": {
   "bands": {
     ".read": "auth != null",
     ".write": "!data.exists() || !newData.exists() && auth != null",
     "$bandId": {
        ".write": "auth != null && data.child('admins').child(auth.uid).val() === true"
     }
   }
}

有没有办法能够在我的/social/bands 树上创建/删除节点,同时能够像/social/bands/$bandId 这样存在的节点,无论路径中是否存在数据?我觉得这是经常发生的事情。

我应该注意,我正在尝试在 Ionic 3 应用程序的上下文中使用 AngularFire 来实现这些规则,如果这会产生任何影响(我不相信它会,作为模拟器正在给我权限错误)。

更新:这是模拟器失败的截图:

这是我试图在模拟器中写入的数据

{
  "admins" : {
    "ruNdZP2Gx6bqsovL8gMlLJP9g0a2" : true
  },
  "creator_id" : "ruNdZP2Gx6bqsovL8gMlLJP9g0a2",
  "followers" : 2,
  "genres" : [ "Classical" ],
  "looking_for_musicians" : true,
  "members" : {
    "ruNdZP2Gx6bqsovL8gMlLJP9g0a2" : true
  },
  "name" : "Radiant and the beach",
  "social_profiles" : {
    "soundcloud" : ""
  }
}

我要写信的路径是/social/bands

这是模拟器中的认证状态:

这是树中的现有数据,其中一个节点已展开:

而错误信息正是我之前提到的 Simulator write denied 问题。

有什么想法我在这里做错了吗?

【问题讨论】:

  • 您能否在模拟器中显示写入失败的屏幕截图,显示您正在写入的路径、您写入的数据、身份验证状态、现有 JSON 数据和错误消息?
  • 嘿,弗兰克,我已经完成了你所要求的一切,尽我所知。知道是什么导致了这里的问题吗?
  • 差不多。 :-) 您可以添加您正在写入的路径和您正在写入的值的屏幕截图吗?这是我更喜欢实际数据屏幕截图的少数情况之一。我经常发现在单个(大)屏幕截图中捕获所有这些(规则、路径、数据、身份验证状态)是最容易的。通常这些对于 SO 来说并不理想,但这是我为这种情况找到的最好的。
  • 我正在写入的路径的屏幕截图和我正在尝试写入的值都在那里。就在整个屏幕截图中获取它而言,它无法展示我正在尝试做的所有事情哈哈。但是你需要的一切都应该在那里:)

标签: json firebase firebase-realtime-database firebase-security


【解决方案1】:

您正在尝试写信给/social/bands。在那个级别上,您有一个规则!data.exists()/social/bands下已经有数据了,比如名为My Awesome Band的乐队。由于数据已经存在,!data.exists() 的计算结果为 false,写入被拒绝。

如果您希望用户能够添加新波段,您应该将该规则下移到 JSON 中特定波段的级别:

"social": {
   "bands": {
     ".read": "auth != null",
     "$bandId": {
        ".write": "auth != null && (
          !data.exists() || !newData.exists() ||
          data.child('admins').child(auth.uid).val() === true
        )"
     }
   }
}

换句话说:任何经过身份验证的用户都可以添加或删除乐队,只有管理员可以修改乐队。

【讨论】:

  • 嘿弗兰克,感谢您的回复!这确实有道理,但奇怪的是,当我应用您建议的规则时,当我尝试写信给/social/bands 时,我仍然得到一个模拟器写权限被拒绝。但是,当我尝试写入树中已经存在的乐队时,例如/social/bands/-KoDm_9yU6JrhOKUPOEW。我是否必须做一些我总是写到某个节点的事情,即使它还不存在?我本来想写 /social/bands 是允许的,因为我需要生成的唯一 ID :( 有什么想法吗?
  • 哇哦。好的,我刚才学到了一些关于 Firebase 安全性的令人难以置信的东西。我错了!我实际上尝试通过我的应用程序输入数据并且它有效!所以你是对的,但我的模拟器只是表现得很时髦:)
  • 所以,是的,我非常感谢你,这已经困扰了我好几个星期了。希望这对其他人也有帮助
  • 很高兴听到你想通了 Stevie!如果控制台中的模拟器给出了错误的结果,我会很感激这个问题的完整截图。
  • @FrankvanPuffelen 你能看到这个问题吗stackoverflow.com/questions/44922710/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 2018-06-02
相关资源
最近更新 更多