【问题标题】:Firebase Database Rules - Get displayNameFirebase 数据库规则 - 获取 displayName
【发布时间】:2018-09-13 09:58:27
【问题描述】:

我将 Firebase 添加到我的网站并创建了一个注册表单。 当用户单击“注册”按钮时,它会使用“Firebase 身份验证”创建用户,然后更新用户的 displayName,最后将有关用户的一些数据添加到数据库中:

firebase.auth().createUserWithEmailAndPassword(email, password).then(function () {

    profile = firebase.auth().currentUser;

    profile.updateProfile({
       displayName: "name-value"
    }).then(function() {

        // Update successful.

        firebase.database().ref("/users/" + profile.uid).set({
            data:{
                country: "country-value",
                city: "city-value"
            }
        });
    });
}).catch(function(error) {
    // Handle Errors here.
});

在我更改数据库规则之前一切正常:

{
    "rules": {
        ".read": true,
        ".write": true
        }
    }
}

收件人:

{
    "rules": {
        "users": {
            ".read": true,
            "$user": {
                ".write": "auth.token.name !== null"
            }
        }
    }
}

我使用guide 中写的 auth.token.name 来检查用户的 displayName 是否存在(我打算稍后让它检查更多相关信息)。 不知何故,“firebase 规则”“认为”auth.token.name 等于 null,即使我之前设置了 displayName。为什么会这样?我该怎么做才能让它发挥作用?

提前致谢:)

【问题讨论】:

  • 您是在尝试使用之前创建的同一个用户,还是尝试注册一个新用户?
  • 我创建页面的目的是注册一个新用户,更改显示名称,最后将一些关于他的数据上传到数据库。

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


【解决方案1】:

首先,Firestore 已经取代了实时数据库,应该用于未来的所有项目 - 更多功能。

关于实时数据库规则,最好检查uid 变量与显示名称。见Variables

{
  "rules": {
    ".read": true,
    "$comment": {
      ".write": "!data.exists() && newData.child('user_id').val() == auth.uid"
    }
  }
}

最后,IIF 您使用 Firebase 身份验证实现数据库安全规则,您必须使用 .onAuthStateChanged 来驱动您的应用程序,因为您的 auth() 变量将在初始页面/应用程序加载时为 null 一秒钟,因为这是异步的方法。所以,不要尝试在 DOM ready 上写或读任何东西。您必须在.onAuthStateChanged 中触发数据库对话,如下所示:

firebase.auth().onAuthStateChanged(function(user) {
    if (user) {
        //USER SIGNED IN. WE ARE READY
    }
    else {
        //USER IS NOT SIGNED IN
    }
});

【讨论】:

  • "Firestore 已取代实时数据库,应该用于所有未来的项目 - 更多功能。"虽然 Firestore 绝对是 Firebase 的最新数据库产品,但这种笼统的说法根本不正确。请参阅firebase.google.com/docs/firestore/rtdb-vs-firestore 进行很好的比较。
  • 感谢您的详细回答,但即使我将部分代码(我更新了 displayName 并将数据添加到数据库中)移动到 .onAuthStateChanged 中,它仍然无法正常工作。然后我按照您的建议尝试了 Firestore 的相同操作(允许写入:如果 request.auth.name != null;),但它也没有工作......它仍然说 displayName 等于 null ......
  • @FrankvanPuffelen 除了分片之外,Realtime DB over Firestore 的用例是什么?您分享的链接显示 Cloud Firestore 是 Firebase 用于移动应用开发的新旗舰数据库。它...具有比实时数据库更丰富、更快的查询和更好的扩展能力。
  • 仅从该页面中引用单引号并不公平,那里的信息太多,无法简单地复制/粘贴在这里(这就是我没有这样做的原因)。即便如此,该页面仍然不完整,缺少关于存在的重要部分(请参阅:firebase.google.com/docs/firestore/solutions/presence)。每个做出选择的人都应该完整阅读该页面,然后做出自己的选择。
  • 我只需要听从 Puf 勋爵 ? 的意见,我不会再说 Firestore 是未来的首选。请原谅过度:-)
【解决方案2】:

我遇到了同样的问题并想出了一个更好的解决方案。 Firebase 有一个名为 custom claims 的功能,适用于我们的用例。您想在可从数据库安全规则访问的 Firebase 匿名身份验证用户上设置一些 id。

解决方案的高层次是创建一个使用管理 api 设置自定义声明的云函数。您不能从客户端设置自定义声明。

接下来,调用云函数更新自定义声明,然后使用Auth.auth().currentUser?.getIDTokenResult(forcingRefresh: true,... 检索包含自定义声明的更新令牌。此步骤至关重要,因为您需要将自定义声明作为后续每个请求的一部分发送。

如果有人真的读过这篇文章,我可以输入一个更详细的实现示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多