Search code examples
swiftgoogle-cloud-platformgoogle-cloud-firestoreclosurescompletionhandler

How to solve this closure completion handler issue?


I have been stuck for almost two days death staring into these functions and want to know why I can't get my desired result.

Here's the first function:

   func getTheSchoolID(completion: @escaping ((String?)-> ())) {
    db.collection("school_users").whereField("userID", isEqualTo: user!.uid).getDocuments { (querySnapshot, err) in
        if let err = err {
            print("There was an error fetching the documents: \(err)")

        } else {
            self.skoolID = querySnapshot!.documents.map { document in
                return SchoolID(schoolID: (document.get("school_id") as! String))
            }
        }
    }

    let fixedID = "\(skoolID)"
    let substrings = fixedID.dropFirst(28).dropLast(3)
    let realString = String(substrings)
    completion(realString)

}

This was the function in an answer given to my last StackOverflow question so I used it and sort of understand the closure completion handler concept.

This next block of code is what I want to happen but doesn't happen.

    getTheSchoolID { [weak self] (realString) in
        if let id = realString {
            DispatchQueue.main.async {
                self?.schoolIDTextF.text = id

            }
        }
    }

Now when i check the textfield in the Viewcontroller it's still empty. The Viewcontroller with the School ID textfield on the bottom.

The collection path is fine the field is correct I'll even add a screenshot of my firestore database for reference. Firestore Database

If anyone can help that would be great. I'll even send a $10 Paypal payment if you give me the answer and it works. That's how much it means to me. Thanks.


Solution

  • getDocuments works asynchronously, you have to call completion inside the closure

    func getTheSchoolID(completion: @escaping (String?) -> Void) {
        db.collection("school_users").whereField("userID", isEqualTo: user!.uid).getDocuments { (querySnapshot, err) in
            if let err = err {
                print("There was an error fetching the documents: \(err)")
                completion(nil)
            } else {
                self.skoolID = querySnapshot!.documents.map { document in
                    return SchoolID(schoolID: document.get("school_id") as! String)
                }
                let fixedID = "\(self.skoolID)"
                let substrings = fixedID.dropFirst(28).dropLast(3)
                let realString = String(substrings)
                completion(realString)
            }
        }
    }
    

    And you are using too many parentheses.

    And the map expression looks pretty weird.