【问题标题】:User's phone number is not updated by a Firebase Cloud FunctionFirebase Cloud Function 未更新用户的电话号码
【发布时间】:2020-07-27 23:03:59
【问题描述】:

我认为这不是 Firebase 特有的。它可能与等待/承诺有更多关系,但我无法弄清楚。

编写 Firebase 函数以允许授权用户更新另一个用户帐户。看起来很简单。请注意 cmets。请注意,1)旧电话号码未定义(如预期),2)新/传入的电话号码是合法的,3)分配后,“新”密码仍然未定义。为什么?!?!?

我错过了什么??? (对不起,我不能让这个问题更简洁!)

module.exports = functions.https.onCall(async (data, context) => {
  var targetUser = await admin.auth().getUser(data.targetUser.uid)
  // Following rule might not make sense! But it works. We know cuz the following later logs output correctly!
  if (
    Boolean(targetUser) && Boolean(context.auth) &&
    Boolean(context.auth.token.companyToken) &&
    (Boolean(context.auth.token.isAdmin) || context.auth.email === targetUser.email)
  ) {
    // Log output appears from the following!
    console.log(`Phone was ${targetUser.phoneNumber}`) // "Phone was undefined" - expected!
    console.log(`Passed-in Phone is ${data.targetUser.phoneNumber}`) // "Phone is (402)555-1212" - Yep!
    // Again, ignore the logic here. It's working! I get the embedded log output
    if (context.auth.email === targetUser.email || context.auth.token.companyToken === targetUser.customClaims.companyToken) {
      // the following appears to not execute! I expect targetUser.phoneNumber to be updated!
      // ... it SHOULD become data.targetUser.phoneNumber (i.e. "(402)555-1212")
      targetUser.phoneNumber = (data.targetUser.phoneNumber ? data.targetUser.phoneNumber : targetUser.phoneNumber)
      console.log(`Phone NOW ${targetUser.phoneNumber}`) // "Phone is NOW undefined"
      // WTF?!?!? It's still undefined?!?!?
      // THIS IS MY PROBLEM RIGHT HERE! WHY IS phoneNumber STILL UNDEFINED?!?!?!
      // You can ignore the rest...
      return updateUser(targetUser).then(() => {
        return {
          success: true
        }
      })
      .catch((e) => {
        return {
        // yadda yadda
        }
      })
    }
  }
  throw new functions.https.HttpsError(
    "not-authorized",
    "Requestor is not authorized to perform this operation on the target user."
  )
})

【问题讨论】:

    标签: javascript firebase promise async-await google-cloud-functions


    【解决方案1】:

    不是您的代码的问题。变量声明的问题,请用 let 代替 var,你已经在路上了。

    module.exports = functions.https.onCall(async (data, context) => {
      //var targetUser = await admin.auth().getUser(data.targetUser.uid);
      // declare the targetUser with let instead of var.
      let targetUser = await admin.auth().getUser(data.targetUser.uid);
      //following later logs output correctly!
      if (
        Boolean(targetUser) && Boolean(context.auth) &&
        Boolean(context.auth.token.companyToken) &&
        (Boolean(context.auth.token.isAdmin) || context.auth.email === targetUser.email)
      ) {
        // Log output appears from the following!
        console.log(`Phone was ${targetUser.phoneNumber}`) // "Phone was undefined" - expected!
        console.log(`Passed-in Phone is ${data.targetUser.phoneNumber}`) // "Phone is (402)555-1212" - Yep!
        // Again, ignore the logic here. It's working! I get the embedded log output
        if (context.auth.email === targetUser.email || context.auth.token.companyToken === targetUser.customClaims.companyToken) {
          // the following appears to not execute! I expect targetUser.phoneNumber to be updated!
          // ... it SHOULD become data.targetUser.phoneNumber (i.e. "(402)555-1212")
          targetUser.phoneNumber = (data.targetUser.phoneNumber ? data.targetUser.phoneNumber : targetUser.phoneNumber)
          console.log(`Phone NOW ${targetUser.phoneNumber}`) // "Phone is NOW undefined"
          // WTF?!?!? It's still undefined?!?!?
          // THIS IS MY PROBLEM RIGHT HERE! WHY IS phoneNumber STILL UNDEFINED?!?!?!
          // You can ignore the rest...
          return updateUser(targetUser).then(() => {
            return {
              success: true
            }
          })
          .catch((e) => {
            return {
            // yadda yadda
            }
          })
        }
      }
      throw new functions.https.HttpsError(
        "not-authorized",
        "Requestor is not authorized to perform this operation on the target user."
      )
    })
    

    如果您仍然遇到任何问题,请告诉我我们会找到另一种方法。

    【讨论】:

    • 实际上这在变量重新分配方面没有任何区别。见medium.com/javascript-scene/…
    • 如果你仔细阅读这篇文章你会注意到, let 变量有一个作用域,但 var 没有任何作用域,它在全局范围内声明变量,这就是为什么有时 var 会在代码中弄得一团糟,因此更喜欢 let用于声明变量而不是 var。
    • "我更喜欢 let 声明变量而不是 var" -> 我完全同意这一点!我的观点是,var 的使用不是 OP 问题的原因。
    • 更改为“让”没有任何区别。但感谢您提供帮助!
    【解决方案2】:

    这是因为targetUserUserRecordgetUser() 方法返回的 Promise 使用 UserRecord 解析)并且您不能像简单的 JavaScript 对象那样更新 UserRecord

    你需要调用updateUser()方法如下:

    const newPhoneNumber = '.....';
    const newUserRecord = await admin.auth().updateUser(data.targetUser.uid, {phoneNumber: newPhoneNumber})
    console.log(newUserRecord.phoneNumber);
    

    另外请注意,您将async/awaitthen() 方法混合使用,不推荐这样做。

    【讨论】:

    • 是的!做到了!我不确定为什么 UserRecord 会受到这样的保护——我一定只是错过了文档中的一些内容,但我永远不会发现。谢谢!关于异步/然后混合......我听到了。我经历了如此多的迭代——认为我的问题是延迟更新或一些诸如此类的废话——我开始怀疑一切。你是今天的英雄!
    • 很高兴我能帮助你 Cliff :-)
    猜你喜欢
    • 1970-01-01
    • 2018-05-17
    • 2019-10-20
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多