如何仅在数据库字段有效时在Firebase中创建用户?

如何仅在数据库字段有效时在Firebase中创建用户?,firebase,firebase-realtime-database,firebase-authentication,Firebase,Firebase Realtime Database,Firebase Authentication,在阅读了许多关于Firebase生态系统中其他用户数据字段(在我的例子中,它只是唯一的用户名)的文章后,我找到了保存和验证用户名的最佳(我希望)变体—将用户名用作/users/下的节点键 我正在验证客户端和数据库规则内部的用户名: ”:“$user.matches(/^[0-9A-Z]{3,18}$/i)和&newData.haschilds(['uid'])和&!data.parent().hasChild($user)”, 我在注册用户时遇到问题。在我的注册方法中,我将用户名保存到数据库中,

在阅读了许多关于Firebase生态系统中其他用户数据字段(在我的例子中,它只是唯一的用户名)的文章后,我找到了保存和验证用户名的最佳(我希望)变体—将用户名用作
/users/
下的节点键

我正在验证客户端和数据库规则内部的用户名:
”:“$user.matches(/^[0-9A-Z]{3,18}$/i)和&newData.haschilds(['uid'])和&!data.parent().hasChild($user)”,

我在注册用户时遇到问题。在我的注册方法中,我将用户名保存到数据库中,成功解决了
createUserWithEmailAndPassword
方法,下面是一段代码:

...
.createUserWithEmailAndPassword(payload.email, payload.password)
.then((user) => {
  // saving additional user information
  firebase
    .database()
    .ref(`users/${payload.username}`)
    .set({
      uid: user.uid,
    })
    .then(() => {
...
客户端验证很好,但显然还不够。我的应用程序工作正常,但如果我们禁用用户名的客户端验证并尝试提交无效的用户名-将创建一个没有用户名的用户

我看到的唯一解决方案是首先创建用户名节点,如果创建成功-尝试注册用户,如果注册不会引发任何错误-继续执行程序,否则在
中。catch
block仅删除使用用户名创建的节点。但对我来说,这似乎是一个非常肮脏的解决方案

我怎样才能优雅地解决这个问题?
谢谢!

这个解决方案对我来说也很肮脏和不雅。我建议不要使用规则方法来验证用户名。因为,正如您所指出的,您无法知道验证何时失败

相反,我建议您在云函数实现中编写一个数据库触发器函数“节点已填充。在这种情况下,您可以验证用户名,以确保它符合您设置的任何标准。如果验证成功,您的客户端应用程序可能会向用户指示,然后继续

如果验证失败,您可以要求用户输入另一个用户名。在进行验证过程时,您甚至可以在客户端中显示进度条或类似的内容


然而,我想补充一点,这可能只是解决这个问题的方法之一,并不一定是最好的方法。虽然我想不出更好的方法,但如果出现其他问题,我完全愿意探索不同的方法

如果要确保已将必填字段保存到数据库中,并且没有其他“未知”字段,则可以使用.validate规则。 将其添加到database.rules.json(或直接在控制台的数据库规则中):

另外,请注意在实时数据库中存储用户的推荐方法,即使用用户的UID作为密钥。 因此,您的用户路径如下所示:

/users/9gZepE9jODX1KZGZ2EEyoX1NyOX4

非常感谢你的回答!然而,在第一步之后,当我们验证并创建了username节点时,我们需要将其存储在客户端的某个位置,以便将来将
uid
添加到此节点。在此步骤中,用户名可能会更改为无效的内容。我们没有办法将用户写入
uid
限制为创建的节点,而不是任何其他节点。(如果我一切都理解正确的话)。我们还需要处理一个案例,如果用户输入用户名,而没有进行实际注册。当然,我们可以删除所有的用户名节点而不使用
uid
,但看起来仍然脏兮兮的。谢谢但如果我们把整个用户创建过程都放在云功能上呢?我想我理解这种混乱。看,
uid
是一个用户属性,在
createUserWithEmailandPassword
时创建。因此,这个
uid
应该作为用户的唯一标识,而不是
用户名
。因此,出于所有目的,您应该使用
uid
作为核心来标识数据库中的各个用户。当然,您也可以添加
用户名
,但这只是额外的。原因是用户对象还包含
uid
。因此,无论何时登录到to客户端应用程序,您都可以从登录用户的
用户
对象中检索
uid
。您真的不需要在客户端存储
用户名
uid
!从安全角度来看,这也是危险的。但如果我们不将uid与用户名关联,我们如何查询用户名呢?
/users/9gZepE9jODX1KZGZ2EEyoX1NyOX4