Получить данные из запроса "getDocument" внутри другого запроса "getDocument" - PullRequest
0 голосов
/ 11 октября 2018

У меня проблема с получением кода из 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.

Спасибо!

1 Ответ

0 голосов
/ 11 октября 2018

Итак, вам нужно получить все теги для одного упражнения, а затем получить другое.и в конце концов получить обработчик завершения вызова для обновления пользовательского интерфейса.Я сделал некоторые изменения в коде, вы можете проверить это.

   var exercisesArray = [Exercise]()
   var listFromFetchExercise = []()  //it will contain all object of array 
   querySnapshot!.documents. set DataType according to that.
   var completion_exercises_Listner: () -> ()

   func fetchExercises(completion: @escaping ([Exercise]) -> ()) {

   let exercisesRef = Firestore.firestore().collection("exercises")

exercisesRef.getDocuments() { (querySnapshot, err) in

    if let err = err {
        print("Error getting documents: \(err)")
    } else {

        listFromFetchExercise = querySnapshot!.documents
        fetchAllExercise()

        DispatchQueue.main.async{
           print("EXERCISE FETCH HAS FINIS")
            completion(exercisesArray)
        }
    }
}
}

func fetchAllExercise(completion: @escaping ([Exercise]) -> ()){

fetchExercise()
completion_exercises_Listner = {
    completion(exercisesArray);
}

}

func fetchExercise(index:Int = 0) {

  let document = listFromFetchExercise[index]

  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]()

  fetchTagsFromIDS(tagsArray) { (tag: [Tag]) in
  exercise_tags.append(contentsOf: 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{
      exercisesArray.append(tag)
      if (index + 1) < exercisesArray.count {
        fetchExercise(index+1,)
      }else{
        //Done
        completion_exercises_Listner()
      }

  }
   ))

  }



 var listofTags = [String]()
 var resultofTags = [Tag]()

   func fetchTagsFromIDS(tagIDS:[String],completion: @escaping (_ tags:[ 
 String]) -> ()){

listofTags = tagIDS;
fetchTagfromID() //Start With first tag

completionListner = {
    completion(resultofTags);
}

}

var completionListner: () -> ()

func fetchTagfromID(index:Int = 0) {

 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")
        resultofTags.append(tag)
        if (index + 1) < listofTags.count {
          fetchTagfromID(index+1,)
        }else{
          //Done
          completionListner()
        }
        //completion(tag)
    }
}
} }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...