在Firebase生态系统中阅读了很多关于其他用户数据字段的文章(在我的例子中,它只是唯一的用户名)后,我找到了保存和验证用户名的最佳(我希望)变体 - 使用用户名作为节点/users/
下的密钥。
我在客户端和内部数据库规则中验证用户名:
": "$user.matches(/^[0-9A-Z]{3,18}$/i)&& newData.hasChildren(['uid']) && !data.parent().hasChild($user)",
我在签约用户时遇到问题。在我的SignUp方法中,我将用户名保存到数据库,成功解决了createUserWithEmailAndPassword
方法,这里是一段代码:
...
.createUserWithEmailAndPassword(payload.email, payload.password)
.then((user) => {
// saving additional user information
firebase
.database()
.ref(`users/${payload.username}`)
.set({
uid: user.uid,
})
.then(() => {
...
客户端验证很好,但显然还不够。我的应用程序工作正常,但是如果我们禁用用户端的用户端验证并尝试提交无效的用户名 - 用户将完全没有用户名。
我看到的唯一解决方案是首先创建用户名节点,如果创建成功 - 尝试签署用户,如果注册不会抛出任何错误 - 继续执行程序,否则在.catch
块中只需用用户名删除创建的节点。但对我来说这似乎是一个非常肮脏的解决方案。
如何以优雅的方式解决这个问题? 谢谢!
答案 0 :(得分:1)
这个解决方案对我来说似乎相当肮脏和不优雅。我建议做的是不使用规则方法来验证用户名。因为,正如您所指出的那样 - 您无法知道验证何时失败。
相反,我建议您在Cloud Functions实现中编写数据库触发器函数。填充“用户名”节点时应触发此功能。在此,您可以验证用户名以确保其符合您设置的任何条件。如果验证成功,您的客户端应用程序可以向用户指示并继续进行。
如果验证不成功,您可以要求用户输入另一个用户名。在验证过程发生时,您甚至可以在客户端中显示进度条或类似内容。
但是,我想补充一点,这可能只是解决这个问题的方法之一,并不一定是最好的方法。虽然我想不出更好的方法,但如果出现其他问题,我完全愿意探索不同的方法!
答案 1 :(得分:0)
如果要确保将必需的字段保存到数据库中,以及没有其他“未知”字段,则可以使用.validate规则。 将其添加到您的database.rules.json(或直接在控制台的数据库规则中):
"users": {
"$uid": {
"email": { ".validate": true },
"displayName": { ".validate": true },
"$other": { ".validate": false },
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
另外,请注意使用UID作为KEY将用户存储在实时数据库中的推荐方法。 因此,您的用户路径将如下所示:
/users/9gZepE9jODX1KZGZ2EEyoX1NyOX4