Firebase onCreate向auth.user添加自定义声明

时间:2020-07-03 17:27:26

标签: reactjs firebase-realtime-database firebase-authentication google-cloud-functions firebase-admin

我正在尝试添加自定义声明,已注册到Firebase。我的Firestore还有另一个user集合,用于保存注册信息记录。现在,我试图保留isRegistered自定义声明,但似乎无法正常工作。

exports.addRegisteredRole = functions.database.ref('/user')
    .onCreate((snap, context) => {
      return // **I added this later, but the issue still remains.**
        admin.auth()
            .setCustomUserClaims(context.auth.uid, {isRegistered: true})
            .then(() => {
                console.log('done', snap)
                return {
                    message: 'done',
                    data: snap
                }
            })
            .catch(err => {
                console.log('something went wrong', err);
                return err
            })
    });

我正在通过以下方式检查此声明

currentUser.getIdTokenResult()
        .then(res => {
            console.log(res.claims.isRegistered)
        })

(验证用户对象)。即使我重新登录,它仍然不确定。我是在做错什么吗,我是Firebase的新手。

4 个答案:

答案 0 :(得分:0)

我怀疑您的Cloud Function在对Auth的调用完成之前被终止了。这样做的原因是,您没有从代码的顶层返回任何内容,这意味着Cloud Functions假定一旦最后的}运行,您的代码就完成了。但是,由于对``的调用是异步的,因此该调用尚未完成,例如您的console.log('done', snap)尚未运行。

exports.addRegisteredRole = functions.database.ref('/user')
.onCreate((snap, context) => {
    return admin.auth()
        .setCustomUserClaims(context.auth.uid, {isRegistered: true})
        .then(() => {
            console.log('done', snap)
            return {
                message: 'done',
                data: snap
            }
        })
        .catch(err => {
            console.log('something went wrong', err);
            return err
        })
});

答案 1 :(得分:0)

我认为您应该使用带有通配符的functions.firestore.document来触发“用户”文档:

exports.addRegisteredRole = functions.firestore.document('/user/{userId}')
.onCreate((snap, context) => { ... });

答案 2 :(得分:0)

问题出在您的onCreate触发器上。您以为在context.auth对象中获取了uid,这是不正确的。

onCreate触发器将在“用户”集合中添加新文档时自动触发。在这种情况下,context.aut.uid是未定义的。您应该在功能日志中对此进行跟踪。

您可以通过几种方式实现您想要做的事情

  1. 如果用户记录文档使用用户ID作为文档名称,则可以执行以下操作
exports.addRegisteredRole =
  functions.firestore
    .document('test/{docId}')
    .onCreate((snap, context) => {
      admin.auth()
        .setCustomUserClaims(snap.id, { isRegistered: true })
        .then(() => {
          console.log('done', snap)
          return {
            message: 'done',
            data: snap
          }
        })
        .catch(err => {
          console.log('something went wrong', err)
          return err
        })
    })
  1. 如果您要用其他名称命名用户记录文档,或者让Firebase为您确定名称,那么您必须在文档数据中将uid作为属性。然后,您使用docSnapshot.data()。uid代替docSnapshot.id,如下所示
exports.addRegisteredRole =
  functions.firestore
    .document('test/{docId}')
    .onCreate((snap, context) => {
      admin.auth()
        .setCustomUserClaims(snap.data().uid, { isRegistered: true })
        .then(() => {
          console.log('done', snap)
          return {
            message: 'done',
            data: snap
          }
        })
        .catch(err => {
          console.log('something went wrong', err)
          return err
        })
    })

祝你好运

答案 3 :(得分:0)

最有可能的问题是您没有将新的自定义声明传播给客户端。请参阅此处:https://firebase.google.com/docs/auth/admin/custom-claims#propagate_custom_claims_to_the_client

这个 github 问题也指出了这一点:https://github.com/firebase/firebase-tools-ui/issues/424

如果您注销并以用户身份重新登录,它应该可以工作。仅刷新登录用户的页面不会刷新用户的 ID 令牌。

由于在 onCreate 触发器中设置自定义声明是一个常见用例,因此最好在专门针对 firestore 的文档 (https://firebase.google.com/docs/auth/admin/custom-claims) 中对此进行说明,因为给定的示例适用于实时数据库.