【问题标题】:Firebase database authentication with email & password使用电子邮件和密码进行 Firebase 数据库身份验证
【发布时间】:2016-12-13 12:45:48
【问题描述】:

我是 Firebase 的新手。我已经建立了一个 firebase 实时数据库,如果读写规则设置为 true,则可以对其进行读写。

我的身份验证有问题。我已经为谷歌和电子邮件加上密码设置了身份验证。

我的目标是允许任何用户读取数据,但只有一个用户(我自己)可以在使用单个电子邮件地址和密码登录后写入数据。

如果我使用 google 登录(规则设置为:auth != null),我可以成功地读取和写入数据库。

如果我使用电子邮件地址和密码登录,我也可以使用相同的规则(auth != null)读取和写入数据库。

我不知道如何将其设置为仅允许使用电子邮件地址和密码登录的单个用户进行写访问。

我已经尝试在规则中包含一个用户节点,但是在使用模拟器时我无法访问(见下文),并且我不知道如何在构建时包含 uid(我可以在登录后获得)参考 - 这是我当前使用的参考(适用于设置为 true 的读写规则):

DatabaseReference databaseReference = mRootReference.child("Action_helper/1/Action_table_of_contents");

我没有在我的数据库中包含用户节点,因为我假设这是由 firebase 身份验证处理的。

这是我的数据布局:

我已经尝试过使用各种规则选项的模拟器。在模拟器中使用这些设置测试访问(选择自定义提供程序选项):

Auth {"provider" : "firebase", "uid" : "Rp3OgoaABMN3hqTv0aF29ECQRCQ2"}

注意:使用我在 Firebase 身份验证中设置的电子邮件地址和密码登录后,我从 Firebase 对象获取提供程序和 uid:

FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    if (user != null) {
        // User is signed in
        userId = user.getUid();
        String provider = user.getProviderId();

我希望在 1) 制定我的规则、2) 我是否应该以及如何更改我的数据结构以及最后 3) 如何将 uid 包含在数据库引用中,我将使用它来将数据写入数据库。

谢谢

【问题讨论】:

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


    【解决方案1】:

    没有用户节点,因此在规则中定义将无济于事。我认为可能有效的规则如下(假设 0 和 1 是 uid):

       {
          "rules": {
    
             "Action_helper":{
    
               "$uid":{
    
                   //user-based security
                   ".read": "auth != null && $uid === auth.uid",
                   ".write": "auth != null", 
    
               }//$uid
    
            }//Action_helper
    
       }// rules
    }
    

    如果我们没有定义规则,则默认检查上述规则,那么它是假的,即在 Action_helper 中,读取和写入都是假的。当涉及到节点uid (其中$表示通配符)时,我们检查登录用户的用户id是否与该节点的uid相同并相应地定义规则。

    强烈推荐去 通过链接 The key to Firebase security - Google I/O 2016 ,它非常有用,易于理解,并且是迄今为止我通过演示示例找到的最佳解释。

    数据布局将取决于您的要求和屏幕。尽管 Firebase 允许 32 级嵌套,但强烈建议尽可能少地嵌套节点。考虑数据布局的其他重要事项是尽可能保持数据非规范化,即使我们 必须跨节点复制字段。

    要在数据库引用中包含 uid,您可以继续附加每个子项:

    DatabaseReference databaseReference = mRootReference.child("Action_helper).child(uid).child("Action_table_of_contents");
    

    所以,这里我们是从根节点到子节点“Action_helper”,再往下是匹配 uid 的子节点,而在那个 uid 中,我们引用的是子节点“Action_table_of_contents”。

    【讨论】:

      【解决方案2】:

      感谢您的帮助。我设法让它(部分)工作,但我不确定我做对了。这是我的数据结构(我已更改名称)- 有一个用户节点(使用身份验证 uid)和两个包含数据的子节点:

      这是我的规则:

      基本上它在模拟器中工作,但在代码中,我能够登录并读写。但是我现在有一个问题,如果我没有登录,那么在查询引用中传递的 uid 为空,如果我将一个虚拟值作为 uid,那么我根本无法访问数据(因为数据在users/the_valid_uid 节点和虚拟 uid 与 the_valid_uid 不匹配)。

      那么如何在不对有效用户的 uid 进行硬编码的情况下构建数据库引用?这样我就可以访问 Addiction_items 和 table_of_contents_items 节点中的数据(我的目标是允许任何人读取两个节点中的数据,但只允许一个用户(我自己)在使用我的电子邮件地址登录后能够写入两个节点和密码?

      谢谢

      【讨论】:

      • 尝试将 ".read":"true", 移动到顶部节点,即将它放在 "rules": node.这将允许任何人从根节点读取直到所有其他子节点,并且无需身份验证即可读取。
      • 要测试它,您可以在模拟器中尝试关闭已验证并尝试从任何节点读取。
      • 感谢 @openSource 的帮助以及指向 firebase youtube 推荐的链接。我发现它很有用。我终于让它按预期工作了。我在写入规则中包含了 && $uid === 'my email login uid' 以便只有该电子邮件登录才能写入用户文件夹(否则任何登录用户都可以在那里写入)。
      猜你喜欢
      • 2019-06-11
      • 1970-01-01
      • 2018-09-03
      • 1970-01-01
      • 2014-01-17
      • 1970-01-01
      • 2018-04-01
      • 2019-03-15
      相关资源
      最近更新 更多