Firebase云函数在返回之前结束



我制作了一个SwiftUI应用程序,它通过多个Firebase云函数获取Firestore数据。我想要得到的Firestore文档的结构如下:

防火仓库结构

现在,我想调用一个名为"getLocationObjectsFromUser";其从用户相关集合LocationIds中获取所有LocationIds然后,我想从具有特定locationId的位置文档中获取所有数据,包括集合";用户ID";。

我尝试过这样的方法,但在这种情况下,firebase函数日志总是告诉我函数已经完成,尽管它还没有完成获取所有数据。正因为如此,我的swift应用程序没有得到任何数据。我如何才能返回我想要的所有数据?

功能代码:

exports.getLocationObjectsFromUser =
functions.https.onCall((data, context) => {
const locations = [];
let userIds = [];
return userRef
.doc(data.userId)
.collection("locationIds")
.where("status", "==", true)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
return locationRef
.doc(doc.id)
.get()
.then((locationDoc) => {
return locationRef
.doc(locationDoc.id)
.collection("userIds")
.get()
.then((querySnapshot1) => {
querySnapshot1.forEach((doc1) => {
userIds.push(doc1.id);
});
const object = {...locationDoc.data(), userIds};
locations.push(object);
userIds = [];
// if statement to avoid return before function has finished running
if (querySnapshot.size == locations.length) {
return {locations: locations};
}
});
});
});
});
});

Swift代码:

func getLocationObjectsFromUser(_ user_id: String, onSuccess: @escaping ([LocationModel]) -> Void, onError: @escaping(_ error: String?) -> Void) {
let dic = ["userId" : user_id] as [String : Any]

self.functions.httpsCallable("getLocationObjectsFromUser").call(dic) { (result, error) in
if let error = error as NSError? {
print("ERROR")
print(error)
onError(error.localizedDescription)
}
if let data = result?.data as? [String: Any] {
print("DATA")
print(data)

// Later on i want to return the LocationModel with something like this: onSuccess(Data).
}
// i do not get any data after calling the function.
}
}

问题是这里的最后一行:

return userRef
.doc(data.userId)
.collection("locationIds")
.where("status", "==", true)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
return locationRef...

由于您在querySnapshot中循环遍历文档,因此其中有多个调用return locationRef...,并且您没有代码确保在Cloud Function终止之前完成所有这些读取。

每当您需要在代码中等待同一级别上的多个操作时,您的答案是使用Promise.all:

return userRef
.doc(data.userId)
.collection("locationIds")
.where("status", "==", true)
.get()
.then((querySnapshot) => {
return Promise.all(querySnapshot.docs.map((doc) => {
return locationRef...

所以变化:

  • 我们返回一个Promise.all(),它只有在完成所有嵌套读取后才能解析。

  • 我们使用querySnapshot.docs.map而不是querySnapshot.forEach,这样我们就得到了一个传递给Promise.all的promise数组。

相关内容

  • 没有找到相关文章

最新更新