【问题标题】:Firebase with Google Cloud Function - Realtime Database Validation to check username not already takenFirebase 与 Google Cloud 功能 - 实时数据库验证以检查尚未使用的用户名
【发布时间】:2023-04-08 13:45:02
【问题描述】:

我发现了各种其他帖子,这些帖子似乎都让我相信我的实现应该可以工作,但仍然缺少一些东西。

这是我的 Firebase 实时数据库规则:

"usernames": {
  ".read" : true,
  ".write" : "auth !== null",
  "$username":{
    ".validate": "!root.child('usernames').hasChild($username)"
  }
}

在我的用户名节点中,例如:

"usernames"
|---"johnDoe123" : "XrG34odsfla82343174094389"
|--- etc.....

我有一个云函数,我通过传递一个令牌来调用它,当云函数运行时,它会尝试通过添加新请求的用户名来更新“用户名”节点,假设用户名尚未被使用。

这是我正在使用的写入 Firebase 用户名节点的函数的一部分:

let newUser = {}
newUser[req.query.username] = decoded.uid
admin.database()
 .ref('usernames')
 .update(newUser)
 .then(() => {
  console.log(`New username <${req.query.username}> added`)
   res.status(200).send(decoded)
 }).catch(e=>{
  console.log('Error', e)
 })

云功能正在更新用户名节点,但我的问题是,如果另一个子节点具有相同的用户名,我需要让它通过验证拒绝更新。到目前为止,我的规则继续允许更新发生,尽管有另一个具有相同用户名的子节点关联到不同的 uid。

任何想法我做错了什么?

【问题讨论】:

  • 如果用户名键已经存在,你可以拒绝它。
  • 是的,我已经通过使用相同的用户名作为已经存在的与不同 uid 关联的密钥进行了测试......然后当我尝试使用相同的用户名和不同的 uid 更新用户名节点时允许更新并覆盖使用用户名存储的现有 uid。

标签: firebase google-cloud-functions


【解决方案1】:

不确定这是否是最好的方法,但它适用于我的目的,即检查用户第一次在我的应用程序中进行设置以确定所请求的用户名是否已被使用。如果是这样,它会发回它已经被采用的 JSON 响应。如果没有被获取,那么它会创建记录,然后发回 JSON 响应成功..

module.exports = functions.https.onRequest((req, res) => {
  cors(req, res, () => {
    const tokenId = req.get('Authorization').split('Bearer ')[1];
    return admin.auth().verifyIdToken(tokenId)
        .then((decoded) => {
            admin.database()
            .ref('usernames')
            .child(req.query.username)
            .once('value', function(snapshot) {
                if(snapshot.val() === null){
                    let newUser = {}
                    newUser[req.query.username] = decoded.uid
                    admin.database()
                    .ref('usernames')
                    .update(newUser)
                    .then(() => {
                        console.log(`New username <${req.query.username}> added`)
                        res.status(200).send({
                            success: true,
                            message: "Username created" 
                        })
                    }).catch(err=>{
                        res.status(500).send(err)
                    })                    
                }
                else{
                    res.status(200).send({
                        success: false,
                        message: "Username already taken"
                    })
                }
            });
        })
        .catch((err) => {
            res.status(401).send(err)
        });
  })
});

【讨论】:

    【解决方案2】:

    如果您使用 Firebase 身份验证来注册所有用户,那么系统会自动告诉用户他们用来注册的电子邮件地址已经是一个帐户。

    您还可以将用户名设置为树路径 /users/AUserName 的一部分,以便在查询时返回 null

    【讨论】:

      猜你喜欢
      • 2018-05-18
      • 2012-03-15
      • 1970-01-01
      • 2018-02-13
      • 2018-11-21
      • 1970-01-01
      • 2019-08-07
      • 2020-11-30
      • 1970-01-01
      相关资源
      最近更新 更多