我已经编写了一些云函数,可以正确地执行批处理。在此实例中,由于数据库模式的原因,我必须搜索与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
}
})
问题不在批处理上。问题是,较大的云函数代码没有返回一个在所有异步工作完成时解决的承诺(请参阅相关文档)。实际上,对于主if(newUsername!==oldUsername)
块,您的代码完全不返回任何内容,这是一个问题。
最低限度,您的代码应该更像这样:
if (newUsername !== oldUsername) {
// ...
const promiseA = conversationQueryA.get()
// ...
const promiseB = conversationQueryB.get()
// ...
return Promise.all([promiseA, promiseB])
}
else {
return null
}
现在,它将返回一个值,无论采用哪一个主要代码路径,它将返回一个承诺,只有在两个异步工作链完成后才解析。