【问题标题】:Why do my Firebase Realtime database rules break my HandleValueChanged?为什么我的 Firebase 实时数据库规则会破坏我的 HandleValueChanged?
【发布时间】:2020-03-29 15:08:07
【问题描述】:

早上好!

我正在 Unity 游戏中开发 Firebase 项目,并且正在努力保护数据库中的数据,但是每当我更新规则时,它都会破坏我的(否则工作的)handlevaluechanged 函数。

数据结构如下:

用户列表-> Firebase_User_ID -> 健康:100, 姓名:福, 等等....

我希望这些数据的规则(至少,稍后我会添加验证)是:

"USER_LIST":
{
    "$UID" :
    {
            ".read": "auth.uid === $UID",
            ".write" : "auth.uid === $UID",
    }
},

在游戏本地,我通过此调用获得了参考:

FirebaseDatabase.DefaultInstance.GetReference("USER_LIST").Child(USER_ID).ValueChanged += HandleValueChanged;

如果我将规则设置为:

            ".read": true,
            ".write" : true

一切都按预期进行。客户端可以更新数据库,handlevaluechanged 完成保持本地数据同步的工作。当我切换到上面验证身份验证 ID 的规则时,客户端仍然可以工作。只要登录了正确的用户 ID,它就可以毫无问题地更新数据库。但是,我的 Handlevaluechanged 从 firebase 获得了权限被拒绝错误,就好像 handlevaluechanged 侦听器在尝试从数据库读取时没有提供正确的用户 ID。

我很困惑,因为规则允许我首先获取参考,并从客户端更新数据库,但我无法从数据库更新客户端?我错过了什么?

我也尝试在 USER_LIST 节点而不是 USER_ID 节点上获取引用,结果相同。

任何见解将不胜感激!先感谢您。

【问题讨论】:

  • 您确定上述附件是在AuthStateChanged 事件处理程序中创建的吗?您需要确保在更新用户状态时连接和断开处理程序。如果和其他 SDK 一样,当前用户将被视为“待定”(几乎被视为null),直到用户的身份验证状态得到确认。在这个短暂的窗口中,上面的规则会抛出权限错误。
  • @samthecodingman 感谢您的回复!没有考虑这个。理论上,一旦用户签名,它应该保持这种状态,对吗?我看到的行为是一旦用户登录,获取参考并启动监听器。我可以很好地上传和下载数据,但是我的规则拒绝了侦听器。您是在建议用户在我不知情的情况下退出,还是在用户成功登录之前激活监听器?再次感谢!
  • 当您的客户端在没有权限的情况下尝试下载数据时,侦听器将被拒绝访问 - 因为当前访问令牌已过期,用户已注销或访问令牌已被无效(例如用户已删除)。用户不一定要退出,但在 Firebase Auth 初始化时,用户的访问令牌通常需要验证和刷新 - 在此过程发生时,您的侦听器将失败。协商完成后,AuthStateChanged 事件处理程序将触发,指示身份验证已准备好使用。
  • 可以把它想象成 JavaScript 的 window.onload = doSomething();,但用于 Firebase 身份验证服务。
  • 您可以随时在数据库模拟器中测试您的规则(单击Data 旁边的Rules 选项卡)。我在这篇文章中对 Cloud Storage 进行了一些尝试,但实时数据库的功能基本相同:medium.com/firebase-developers/…。如果您想快速进行模糊测试以查看这是否是您的问题,您也可以断言 FirebaseAuth.DefaultInstance.CurrentUser != null

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


【解决方案1】:

在忽略这个问题一段时间并处理其他错误之后,我发现了真正的问题并想发布以防其他人发现自己在这个泡菜中。

我有一个专门用于登录用户的 Unity 场景,该场景创建了经过身份验证的 Firebase 用户,然后跳转到了一个新场景。在那个新场景中,我搜索了用户登录时创建的本地用户对象,然后设置了数据库引用和 handleValueChanged 侦听器。

我认为问题在于搜索用户是异步完成的(我还没有做更多的研究来确认这一点,但我在这个特定案例中的测试似乎表明是这种情况),所以任务开始了,在查找用户凭据时,它创建了数据库引用并添加了一个带有空用户的侦听器。之后,任务完成,用户不再为空,但监听器已经在监听。

然后,如果我进行数据库读取或写入,则读取或写入调用来自经过身份验证的用户,并且只要满足 RTB 规则,就会执行。成功的写入将触发 handlevaluechanged 侦听器并绘制一个权限被拒绝错误,因为侦听器没有与之关联的经过身份验证的用户 ID(同样,我得出这个结论是基于对这个特定项目的观察和测试,而不是研究)。

只需在创建本地用户对象后将数据库引用添加到本地用户对象,而不是搜索用户然后建立引用即可解决我的所有问题。

我希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2021-01-14
    • 2013-06-25
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 2011-06-06
    • 1970-01-01
    相关资源
    最近更新 更多