Reactjs Firebase onCreate将自定义声明添加到auth.user

Reactjs Firebase onCreate将自定义声明添加到auth.user,reactjs,firebase-realtime-database,firebase-authentication,google-cloud-functions,firebase-admin,Reactjs,Firebase Realtime Database,Firebase Authentication,Google Cloud Functions,Firebase Admin,我正在尝试添加一个自定义声明,已注册到firebase。我的firestore有另一个用户集合来保存注册信息记录。现在我正试图保留一个isRegistered custom claim,但我似乎无法让它工作 exports.addRegisteredRole = functions.database.ref('/user') .onCreate((snap, context) => { return // **I added this later, but the is

我正在尝试添加一个自定义声明,已注册到firebase。我的firestore有另一个
用户
集合来保存注册信息记录。现在我正试图保留一个isRegistered custom claim,但我似乎无法让它工作

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的新手。

我怀疑您的云函数在对Auth的调用完成之前被终止。原因是您没有从代码的顶层返回任何内容,这意味着云函数假定在最终的
}
运行后代码就完成了。但由于对``的调用是异步的,因此该调用尚未完成,例如,您的
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
        })
});

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

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

问题在于onCreate触发器。您假设您在context.auth对象中获取uid,这是不正确的

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

你可以通过两种方式实现你想做的事情

  • 如果用户记录文档的名称为用户Id,则可以执行以下操作
  • 如果要使用其他名称命名用户记录文档,或让firebase为您决定名称,则必须在文档数据中将uid作为属性。然后使用docSnapshot.data().uid而不是docSnapshot.id,如下所示

  • 祝您好运

    最可能的问题是您没有将新的自定义声明传播给客户。请看这里:

    github的这一问题也指出:

    如果您注销并与用户一起重新登录,则应该可以正常工作。仅为登录用户刷新页面不会刷新用户的ID令牌


    由于在onCreate触发器中设置自定义声明是一个常见的用例,因此最好在文档()中专门针对firestore对此进行说明,因为给定的示例是针对实时数据库的。

    Frank是对的,您不会返回在异步工作完成后解决的承诺。从数据库触发器返回数据也没有什么意义。这些数据不会去任何地方或做任何事情。是的,我已经解决了。但它给出了同样的结果。“同样的结果”很不幸很难得到帮助。到底发生了什么?调用是否显示在函数日志输出中?您的
    控制台.log
    语句是否显示?我做了此更改。但结果是一样的。问题仍然存在。但是当我使用via
    functions.http.onCall
    执行此操作时,它工作得非常好。我只是想通过触发onCreate使它更安全。
    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
            })
        })
    
    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
            })
        })