#swift #firebase #google-cloud-firestore #swiftui
# #swift #firebase #google-облако-firestore #swiftui
Вопрос:
Я пытаюсь одновременно получить данные документа и справочные данные и поместить данные в пользовательскую структуру, которая состоит из массива строк.
Когда я запускаю приведенный ниже код, добавляются только ссылки DocumentReference типа «item1_» и «item2_».
Коллекция «раздел» содержит несколько документов. Каждый документ имеет 2 ссылки на документы. Я могу получить правильную ссылку на документ, но я не могу прочитать его данные в той же функции.
Как я могу получить оба данных из Firestore?
func getall_sec(top: String, mid: String){ref.collection("top_hierarchy").document(top).collection("mid_hierarchy").document(mid).collection("section").addSnapshotListener(){ (snap, err) in
guard let docs = snap else {
self.nosecs = true
return
}
if docs.documentChanges.isEmpty{
self.nosecs = true
return
}
docs.documentChanges.forEach { (doc) in
if doc.type == .added{
let item1_ = doc.document.data()["item1"] as! DocumentReference
let item2_ = doc.document.data()["item2"] as! DocumentReference
item2_.getDocument(){ (querySnapshot, err) in
if let err = err {
print("Error getting documents: (err)")
} else {
self.item2_name = querySnapshot?.data()?["low"] as! String
self.item2_ImageName = querySnapshot?.data()?["ImageName"] as! String
}
}
item1_.getDocument(){ (querySnapshot, err) in
if let err = err {
print("Error getting documents: (err)")
} else {
self.item1_name = querySnapshot?.data()?["low"] as! String
self.item1_ImageName = querySnapshot?.data()?["ImageName"] as! String
}
}
self.sections.append(SectionModel(id: doc.document.documentID, item_name1: self.item1_name, item_ImageName1: self.item1_ImageName, item_name2: self.item2_name, item_ImageName2: self.item2_ImageName))
}
}
}
}
Ответ №1:
Основная проблема заключается в том, что getDocument является асинхронным, и код self.sections.append фактически будет выполняться перед кодом в замыканиях, следующих за двумя функциями get.
item2_.getDocument(){ (querySnapshot2, err2) in
//this code will execute at some point
}
item1_.getDocument(){ (querySnapshot1, err1) in
//this code will execute at some point
}
//this code will execute before the code in the two above getDocument closures.
self.sections.append(SectionModel(id: doc.document.documentID...
одним из решений является вложение вызовов, чтобы они выполнялись по порядку (это не лучшее решение, но демонстрирует концепцию)
item2_.getDocument(){ (querySnapshot, err) in
item1_.getDocument(){ (querySnapshot, err) in
self.sections.append(SectionModel(id: doc.document.documentID...
}
}