Как я могу получить данные документа и справочные данные одновременно?(Firestore, Swift)

#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...
   }
}