Search code examples
swiftgoogle-cloud-firestoresyntaxsegue

How can I change the order of functions triggered?


I'm working on Swift coding and have question in my code. in the code below, I'm trying to get the information of the table view cell first and then perform segue. I'm also using Firestore to save the data. The problem is when I use print, I can see segue triggered!!! first and then document saved!!. Since I want to pass the value of doc.documentID, to the next view controller, I want to save the documentID before the perform segue is triggered.....

class HomeViewController: UIViewController {
    var gameDocumentID = ""
// more codes here...
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == K.homeToGameScreen {
            let gameScreenVC = segue.destination as! GameScreenViewController

                gameScreenVC.gameDocumentID = gameDocumentID
        }
    }
}


        extension HomeViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    // serch game db where player1 is ready to play
    
    db.collection(K.FStore.newGameCpllection).whereField(K.FStore.uID, isEqualTo: players[indexPath.row].uID).addSnapshotListener { (querySnapshot, err) in
        if let err = err {
            print("Error getting game db: \(err)")
        } else {
            
            for doc in querySnapshot!.documents {
                
                print("document saved!!")
                self.gameDocumentID = doc.documentID
            
            self.db.collection(K.FStore.newGameCpllection).document(self.gameDocumentID).updateData([
                K.FStore.player2Field: self.playerInfo[K.FStore.nameField]!
            ]) { err in
                if let err = err {
                    print("Error updating document: \(err)")
                } else {
                    print("Document successfully updated")
                    
                }
                print("segue triggered!!!")
                self.performSegue(withIdentifier: K.homeToGameScreen, sender: self)
                }
            }
            }
        
        }

    }
}

Solution

  • Data is loaded from Firebase asynchronously. Since that may take some time, your completion handler is called later than you might expect.

    For this reason, any code that needs the data from the database, needs to be inside the completion handler, or be called from there.

    So the simplest fix is to move the performSegue into the callback:

    extension HomeViewController: UITableViewDelegate {
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
        db.collection(K.FStore.newGameCpllection)
          .whereField(K.FStore.uID, isEqualTo:players[indexPath.row].uID)
          .addSnapshotListener { (querySnapshot, err) in
                if let err = err {
                    print("Error getting game db: \(err)")
                } else {
                    for doc in querySnapshot!.documents {
                
                    print("document saved!!")
                    self.gameDocumentID = doc.documentID                
                    self.db.collection(K.FStore.newGameCpllection).document(self.gameDocumentID).updateData([
                        K.FStore.player2Field: self.playerInfo[K.FStore.nameField]!
                    ]) { err in
                        if let err = err {
                            print("Error updating document: \(err)")
                        } else {
                            print("Document successfully updated")
                        }
                        print("segue triggered!!!")
                        self.performSegue(withIdentifier: K.homeToGameScreen, sender: self)
                    }
                }
                
            }
        }
        }
    }
    

    Also see: