Требуется ли обработчик завершения для вызова данных из firebase? - PullRequest
1 голос
/ 25 февраля 2020

Я пытаюсь вызвать данные из firebase. Проблема в том, что данные глубоко вложены, и я не думаю, что смогу это изменить.

Поэтому я пытаюсь вызывать значения из firebase, которые затем я могу использовать для ссылки на новые значения. Проблема возникает, когда my for l oop не завершается до вызова следующего этапа, то есть счетчик словаря для следующего этапа равен 0, поэтому моя следующая функция не вызывается?

Есть ли способ сделать это достаточно?

Пожалуйста, помогите?

Вот мой код:

func fetchBuyer(search: String, user: String, completion: @escaping ([Post]) -> (), withCancel cancel: ((Error) -> ())?) {
    let ref = Database.database().reference().child("posts").child(user).child(search).child("purchases")
    ref.observeSingleEvent(of: .value, with: { (snapshot) in
        guard let dictionaries = snapshot.value as? [String: Any] else {
            completion([])
            return
        }

        let keys: [String] = dictionaries.map({ $0.key })
        var newdictionaries = [String: String]()

        for i in keys {
            let newref = Database.database().reference().child("posts").child(user).child(search).child("purchases").child(i).child("purchaser")
            newref.observeSingleEvent(of: .value, with: { (snapshot) in
                newdictionaries[i] = snapshot.value as? String
                print("THESE ARE MY PURCHASES ID-->", newdictionaries.values)///prints out ["-M0pTHtZXYUVQT7DCLj-", "-M0pU79uQCCnBunAEkJN"]
            })
        }

        var buyerPosts = [Post]()
        print("newdictionaries.count--->", newdictionaries.count)//this print is 0
        newdictionaries.forEach({ (postId, value) in
            Database.database().fetchPost(withUID: user, postId: postId, completion: { (post) in
                buyerPosts.append(post)
                if buyerPosts.count == newdictionaries.count{
                    completion(buyerPosts)
                }
            })
        })
    }) { (err) in
        print("Failed to fetch posts for buyers:", err)
        cancel?(err)
    }
}

Попытка ответа:

            let g = DispatchGroup()  //// 1
           for i in keys{
               g.enter()   //// 2
               let newref = Database.database().reference().child("posts").child(user).child(search).child("purchases").child(i).child("purchaser")
            print("now")
            newref.observeSingleEvent(of: .value, with: { (snapshot)
                       newdictionaries[i] = snapshot.value as? String
                        print("print new dictionaries-->", newdictionaries)
                       // complete here
                Database.database().fetchPost(withUID: user, postId: newdictionaries[i]!, completion: { (post) in
                                buyerPosts.append(post)
                                g.leave() //////// 3
                         })
                    })
             }
         g.notify(queue: DispatchQueue.main) {
            print("finished!!!")
           completion(buyerPosts)
         }

1 Ответ

1 голос
/ 25 февраля 2020

Вам нужна группа рассылки и вложенные звонки

    let g = DispatchGroup()  //// 1

    for i in keys{
        g.enter()   //// 2
        let newref = Database.database().reference().child("posts").child(user).child(search).child("purchases").child(i).child("purchaser")
             newref.observeSingleEvent(of: .value, with: { (snapshot) 
                newdictionaries[i] = snapshot.value as? String 
                // complete here 
                    Database.database().fetchPost(withUID: user, postId: postId, completion: { (post) in
                         buyerPosts.append(post)
                         g.leave() //////// 3
                  })

             })
      }

 /// 4
  g.notfiy(queue.main) {
    completion(buyerPosts)
  }
...