У меня проблема с получением кода из Firestore.
В моем коде есть 2 класса: Упражнение и Тег.И в моей базе данных FirestoreDatabase есть 2 коллекции: упражнения и теги
Мне нужно просмотреть все документы «упражнений» из коллекции «упражнений».Каждый документ "упражнения" имеет поле с именем "tags", которое представляет собой массив строк.Каждая строка массива содержит «id», который ссылается на документ, который «tag» имеет в коллекции «tags».Итак, запрос этого идентификатора в коллекции «тегов» позволяет мне получить правильный документ «тега» и получить доступ ко всем его данным.И это именно то, что я хочу сделать в своем коде.
Мне нужно объединить все упражнения в объект Exercise, и для этого мне нужно использовать запрос getDocument внутри другого запроса getDocument, чтобы получить «теги»."из упражнения" из коллекции "тегов"
Это мои классы "Метка и упражнение":
class Tag {
var id: String?
var type: String?
var description: String?
init(id: String, type: String, description: String) {
self.id = id
self.type = type
self.description = description
}
}
class Exercise {
let id: String?
let group: String?
let tags: [Tag]
let title : String!
init(id: String, group: String, tags: [Tag], title: String){
self.id = id
self.group = group
self.tags = tags
self.title = title
}
}
И вот код, из которого я беру свои "упражнения" из базы данных Firestore:
func fetchExercises(completion: @escaping ([Exercise]) -> ()) {
let exercisesRef = Firestore.firestore().collection("exercises")
exercisesRef.getDocuments() { (querySnapshot, err) in
var exercisesArray = [Exercise]()
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
//print("\(document.documentID) => \(document.data())")
let myData = document.data()
let exercise_ID = document.documentID
let exercise_group = myData["Group"] as! String
let tagsArray = myData["Tags"] as! [String]
var exercise_tags: [Tag] = [Tag]()
for tag in tagsArray {
let tagID: String = tag
fetchTagfromID(tagID: tagID) { (tag: Tag) in
exercise_tags.append(tag)
}
}
let exercise_title = myData["Title"] as! String
exercisesArray.append(Exercise(id: exercise_ID,
group: exercise_group,
tags: exercise_tags,
title: exercise_title,
))
}
DispatchQueue.main.async{
print("EXERCISE FETCH HAS FINIS")
completion(exercisesArray)
}
}
}
}
func fetchTagfromID(tagID: String, completion: @escaping (Tag) -> ()) {
let tagRef = Firestore.firestore().collection("tags").document(tagID)
tagRef.getDocument() { (document, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
let myData = document?.data()
let tagDescription: String = myData!["description"] as! String
let tagType: String = myData!["type"] as! String
let tag: Tag = Tag(id: tagID, type: tagType, description:
tagDescription)
DispatchQueue.main.async{
print("TAGS FETCH HAS FINISHED")
completion(tag)
}
}
}
}
Мои проблемы связаны с выполнением кода хронирования (очередей).
Мне нужно сначала заполнить "exerc_tags" (вторичный запрос getDocument), а затем продолжить и завершить fetchExercise (основной запрос getDocument)но Firestore не позволяют (или не знают как) сделать это.Сначала код завершает основной запрос getDocument (fetChExercises), а затем возвращается к завершению вторичного запроса getDocument (fetchTagfromID).
В заключение мне нужно, чтобы во время выполнения я получил этот журнал:
TAGS FETCH HAS FINISHED
EXERCISES FETCH HAS FINISHED
и теперь я получаю обратное.
Знаете ли вы, ребята, как решить эту проблему?Возможно, изменив очередь отправки ...
Теперь я понимаю, как решить проблему, выполнив это в два этапа, но элегантное решение - выполнить все за один шаг.Это, fetchExercises.
Спасибо!