Firebase数据库规则 - 获取displayName

时间:2018-04-04 00:12:40

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

我将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"
            }
        }
    }
}

我使用 auth.token.name ,因为它是在guide中写的,用于检查用户的displayName是否存在(我打算让它进行更多检查)以后的事情)。 某种方式"火力基地规则" '认为' auth.token.name 等于null,即使我之前设置了displayName。为什么会发生这种情况,我该怎么做才能使它发挥作用?

提前致谢:)

2 个答案:

答案 0 :(得分:3)

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

重新实时数据库规则,最佳做法是检查uid变量与显示名称。见Variables

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

最后,您使用Firebase身份验证实施数据库安全规则的IIF,您必须使用.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
    }
});

答案 1 :(得分:0)

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

该解决方案的高层是制作一个使用admin api设置自定义声明的Cloud Function。您不能从客户端设置自定义声明。

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

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