当前位置: 首页 > 知识库问答 >
问题:

并非所有代码路径都返回多批写入的值Google Firestore Cloud函数Typescript

端木朝
2023-03-14

我已经编写了一些云函数,可以正确地执行批处理。在此实例中,由于数据库模式的原因,我必须搜索与userA uid或userB uid字段匹配的文档。

这个模式并不是最聪明的,如果有更好的解决方案,请让我知道。它用于应用程序的消息传递方面。其中每个文档都有一组userA和UserB的字段。

当用户更改其用户名,并且“Conversations”集合中包含该用户数据的文档必须更新时,此功能将被触发。

我必须执行两个单独的查询,因为我正在搜索两个不同的文档字段,这些字段可能包含需要更新其信息的用户的id。

批处理写入使用用户为userA的实例或他们为UserB的实例的新信息更新文档。

我认为,通过为每个查询创建两个单独的批处理并正确地返回它们,它将“返回所有代码路径”,然而tsLint告诉我的是不同的。

即使当我试图解释不存在的已发送文档时:Firebase cloud function typescript error“不是所有代码路径都返回一个值”

我仍然没有正确返回所有代码路径。

示例:

//Changed from this
const batch = db.batch()
  querySnapshot.forEach(doc => {
    batch.update(doc.ref, {
      profileImageURL: newProfilePic
    })
  })
  return batch.commit()

//To this
const batch = db.batch()
querySnapshot.forEach(doc => {
  if (!doc.exists) {
    console.log("Document does not exists: " + doc.data())
  } else {
    batch.update(doc.ref, {
      userAusername: newUsername
    })
  }
})
return batch.commit()

这里是完整的功能

export const updateUserUsernameInConversations = functions.firestore
  .document('users/{userId}')
  .onUpdate(async (change, context) => {
    const { userId } = context.params

    const newUsername = change.after.data().username
    const oldUsername = change.before.data().username
    if (newUsername !== oldUsername) {
      const conversationsRef = db.collection('Conversations')
      const conversationQueryA = conversationsRef.where('userAuid', '==', userId)
      const conversationQueryB = conversationsRef.where('userBuid', '==', userId)

      conversationQueryA.get()
        .then(querySnapshot => {
          if (querySnapshot.empty) {
            return null
          } else {
            const batch = db.batch()

            querySnapshot.forEach(doc => {
              batch.update(doc.ref, {
                userAusername: newUsername
              })
            })
            return batch.commit()
          }
        })
 
      conversationQueryB.get()
        .then(querySnapshot => {
          if (querySnapshot.empty) {
            return null
          } else {
            const batch = db.batch()
            querySnapshot.forEach(doc => {
              batch.update(doc.ref, {
                userBusername: newUsername
              })
            })
            return batch.commit()
          }
        })
    } else {
      return null
    }
  })

共有1个答案

施恩
2023-03-14

问题不在批处理上。问题是,较大的云函数代码没有返回一个在所有异步工作完成时解决的承诺(请参阅相关文档)。实际上,对于主if(newUsername!==oldUsername)块,您的代码完全不返回任何内容,这是一个问题。

最低限度,您的代码应该更像这样:

    if (newUsername !== oldUsername) {
      // ...
      const promiseA = conversationQueryA.get()
        // ...
      const promiseB = conversationQueryB.get()
        // ...
      return Promise.all([promiseA, promiseB])
    }
    else {
      return null
    }

现在,它将返回一个值,无论采用哪一个主要代码路径,它将返回一个承诺,只有在两个异步工作链完成后才解析。

 类似资料:
  • 我正在研究一个使用反射调用另一个方法的方法。然而,“其他方法”可以引发异常,我想用它的原始堆栈信息和内部异常来传播该异常。这只是因为使用反射的方法不应该处理异常,调用方应该处理异常。 下面是代码的简化版本: 该代码显然不会编译,因为Test方法(根据编译器)并不总是返回值。我可以在异常DispatchInfo之后添加一个return false。捕获,但我想知道是否有更好的方法来实现同样的目标。不

  • 问题内容: 假设我的数据库方案如下: 如果我运行第一个查询来获取所有产品及其用户(如果有的话),则会得到以下信息: 对我来说看上去很好。现在,如果我想做同样的事情,除了我希望每行有一个产品,并使用级联的用户名(如果有任何用户,否则为NULL): 如果没有产品的用户,即使存在 LEFT JOIN ,GROUP_CONCAT也会阻止mysql为该产品生产线。 这是预期的MySQL行为吗? 有什么办法可

  • 本文向大家介绍Python 函数返回值的示例代码,包括了Python 函数返回值的示例代码的使用技巧和注意事项,需要的朋友参考一下 0x 00 返回值简介 回顾下,上一节简单介绍了函数及其各种参数,其中也有简单介绍 print 和 return 的区别,print 仅仅是打印在控制台,而 return 则是将 return 后面的部分作为返回值作为函数的输出,可以用变量接走,继续使用该返回值做其它

  • 在这个高尔夫球答案中,我看到了一个技巧,其中返回值是第二个没有传入的参数。 从gcc的程序集输出来看,当代码复制时,它将结果存储在

  • Go语言内置支持多返回值,这个在Go语言中用的很多,比如一个函数同时返回结果和错误信息。 package main import "fmt" // 这个函数的返回值为两个int func vals() (int, int) { return 3, 7 } func main() { // 获取函数的两个返回值 a, b := vals() fmt.Println(a

  • 我正在等待(从USSD请求中)检索一个值,以便返回它(getUSSD):