更新+ Permission_denied

时间:2019-09-14 08:34:01

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

我在拒绝权限的情况下将数据更新到RDB时发现了奇怪的行为。

示例,其中包含用于再现“错误”的最少代码:

getBooks() {
   firebase.database().ref("books/1").on("value", data => {
      console.log("foo", data.val());
   }
}

setAuthor() {
   firebase.database().ref("books/1").update({ "author": "foo" });
}

假设我们在getBooks上有一个订阅,以获取每次更改的数据。

现在让我们使用setAuthor方法来更新作者。

如果我们拥有所需的权限,会发生什么?

→一切正常。日志“ foo”将弹出一个新的节点,其中author =“ foo”。

如果我们没有所需的权限,会发生什么?

→3个日志按以下顺序:

  • “ foo”将弹出并带有author =“ foo”的新节点。
  • @ firebase / database:防火墙警告:/ books / 1上的更新失败:Permission_denied
  • “ foo”将弹出旧节点(带有原始作者)。

注意:这种奇怪的行为仅在尝试更新author的客户端上发生(很幸运)。更新无法正常进行。确认我打开了另一个浏览器,并且没有弹出日志。

任何解释为什么它像更新一样起作用?

1 个答案:

答案 0 :(得分:1)

这是预期的行为,但起初确实会造成混淆。

在客户端上执行写操作时,Firebase会立即在本地侦听器上触发事件。这样做不需要等待服务器的响应,这是Firebase立即向本地用户写入内容的部分原因。

然后将写操作发送到服务器,并等待响应。响应可以是对写操作的确认或拒绝。如果服务器拒绝写入操作,则Firebase客户端会触发事件以使客户端应用再次进入正确状态。

以图表形式:

     client app             SDK              Server
       +                     +                  +
       |                     |                  |
       |    write("new")     |                  |
       +-------------------->|                  |
       |                     |                  |
       |  on("value", "new") |                  |
       |<--------------------+                  |
       |                     |                  |
       |                     |   write("new")   |
       |                     +----------------->|
       |                     |                  |
       |                     |      reject      |
       |                     |<-----------------+
       |                     |                  |
       |  on("value", "old") |                  |
       |<--------------------+                  |
       |                     |                  |
       +                     +                  +