我制作了一個 SwiftUI 應用程式,它通過多個 Firebase 云函式獲取其 Firestore 資料。我想要獲取的 Firestore 檔案的結構如下:
Firestore 結構
現在,我想呼叫一個名為“getLocationObjectsFromUser”的云函式,它從用戶相關的集合locationIds中獲取所有LocationIds。然后,我想從具有特定locationId的位置檔案中獲取所有資料,包括集合“UserIds”。
我嘗試過這樣的事情,但在這種情況下,firebase 函式日志總是告訴我函式已經完成,盡管它還沒有完成獲取所有資料。正因為如此,我的 swift App 沒有獲得任何資料。我怎樣才能回傳我想要的所有資料?
功能代碼:
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)
one rror(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.
}
}
uj5u.com熱心網友回復:
問題是這里的最后一行:
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...
所以變化:
我們回傳 a
Promise.all()只有在所有嵌套讀取完成后才決議。我們使用
querySnapshot.docs.map而不是querySnapshot.forEach,以便我們得到一組要傳遞給的承諾Promise.all。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/411872.html
標籤:
