Node.js 文档更新时的云函数触发器

Node.js 文档更新时的云函数触发器,node.js,firebase,google-cloud-firestore,google-cloud-functions,Node.js,Firebase,Google Cloud Firestore,Google Cloud Functions,如果users/{userId} 我有一个signIn方法,每次用户登录时都会触发该方法 signin: (email, password, setErrors) => { firebase .auth() .signInWithEmailAndPassword(email, password) .then(() => { const isVerified = firebase.auth().currentUser.emai

如果
users/{userId}

我有一个signIn方法,每次用户登录时都会触发该方法

signin: (email, password, setErrors) => {
    firebase
      .auth()
      .signInWithEmailAndPassword(email, password)
      .then(() => {
        const isVerified = firebase.auth().currentUser.emailVerified
        const userUid = firebase.auth().currentUser.uid
        const db = firebase.firestore()
        if (isVerified) {
          db.collection('/users')
            .doc(userUid)
            .update({ isVerified: true })
        }
      })
      .catch(err => {
        setErrors(prev => [...prev, err.message])
      })
  },
没什么奇怪的,除了基本的登录功能外,它还检查用户是否验证了他们的电子邮件,如果验证了,它将为该用户更新收集。这里的一切都按计划进行

然而,我似乎无法启动我的云功能

基本上,它在监听用户集合的变化。如果
users/{userId}
文档已验证
且用户电子邮件地址以
xxxx
结尾,则应授予他们管理员权限

exports.updateUser = functions.firestore.document('users/{userId}').onUpdate((change, context) => {
  const after = change.after.data()
  if (after.isVerified) {
    firebase.auth().onAuthStateChanged(user => {
      if (user.emailVerified && user.email.endsWith('@xxxx')) {
        const customClaims = {
          admin: true,
        }
        return admin
          .auth()
          .setCustomUserClaims(user.uid, customClaims)
          .then(() => {
            console.log('Cloud function fired')
            const metadataRef = admin.database().ref('metadata/' + user.uid)
            return metadataRef.set({ refreshTime: new Date().getTime() })
          })
          .catch(error => {
            console.log(error)
          })
      }
    })
  }
})

现在函数没有启动,有什么想法吗?

云函数中的代码作为管理帐户运行,无法使用常规Firebase身份验证SDK检索。事实上,您应该只在云函数代码中使用Firebase Admin SDK,其中不存在
onAuthStateChanged
方法

还不完全清楚您希望此代码对用户执行什么操作,但是如果您想检查路径中的
uid
用户是否具有已验证的电子邮件地址,可以使用Admin SDK


要确保路径中的
uid
是执行操作的用户的真实uid,可以使用安全规则,如上的文档所示。

云函数中的代码作为管理帐户运行,无法使用常规Firebase身份验证SDK检索。事实上,您应该只在云函数代码中使用Firebase Admin SDK,其中不存在
onAuthStateChanged
方法

还不完全清楚您希望此代码对用户执行什么操作,但是如果您想检查路径中的
uid
用户是否具有已验证的电子邮件地址,可以使用Admin SDK


要确保路径中的
uid
是执行操作的用户的真实uid,可以使用安全规则,如上的文档所示。

我支持Frank所说的

您可以通过以下方式使用admin获取用户:

if (after.isVerified) {
  admin.auth().getUser(userId)
    .then((userData) => { ... 

我支持弗兰克说的话

您可以通过以下方式使用admin获取用户:

if (after.isVerified) {
  admin.auth().getUser(userId)
    .then((userData) => { ... 

它可能正在发射,只是没有进入那个大的if(){…}你怎么知道它没有发射?您是否检查了您的函数日志并检查它是否未启动?是的,我检查了,日志为空在if(after.isVerified){}之前放置一个日志,然后重试。类似于console.info(JSON.stringify(after))的东西好的,看起来它正在启动,但是代码块(after.isVerified)没有执行……是否可能我无法使用firebase.auth()检索用户?这确实是问题所在。我会写一个答案。它可能正在开火,只是没有进入那个大的if(){…}你怎么知道它没有开火?您是否检查了您的函数日志并检查它是否未启动?是的,我检查了,日志为空在if(after.isVerified){}之前放置一个日志,然后重试。类似于console.info(JSON.stringify(after))的东西好的,看起来它正在启动,但是代码块(after.isVerified)没有执行……是否可能我无法使用firebase.auth()检索用户?这确实是问题所在。我会写一个答案。我试图授予特定用户管理员访问权限,我真的不想在客户端这样做,所以我选择了云功能。上述方法在用户验证其电子邮件地址后执行,如果地址以
xxx
授予管理员访问权限结尾-我不确定这是否是最好的方式,但我只需要一种安全的方式授予管理员访问权限,基于currentUser.props这是我在回答中描述的:您可以使用AdminSDK来查找用户的属性。我添加了一个关于如何使用安全规则来确保UID正确的解释。我正在尝试向特定用户授予管理员访问权限,我不想在客户端这样做,所以我选择了云功能。上述方法在用户验证其电子邮件地址后执行,如果地址以
xxx
授予管理员访问权限结尾-我不确定这是否是最好的方式,但我只需要一种安全的方式授予管理员访问权限,基于currentUser.props这是我在回答中描述的:您可以使用AdminSDK来查找用户的属性。我添加了关于如何使用安全规则来确保UID正确的说明。