-4

Within my function to load users I'm able to retrieve a value. However, when I want to assign it to my variable outside the function it has nothing, as shown in the login function.

Load User Function

func loadUser(userid: String) -> User {
   //print(userid)
   let userid = "56ldZFJiv0dpfaABzo78"
   var user = User()
   let docRef = db.collection("users").document(userid)
   docRef.getDocument { (document, error) in
       if let document = document {
           let first = document.data()!["first"] as! String
           let last = document.data()!["last"] as! String
           let position = document.data()!["position"] as! String
           let company = document.data()!["company"] as! String
           let email = document.data()!["email"] as! String
           let address = document.data()!["address"] as! String
           let userID = document.data()!["userID"] as! String

           //Initalize user
          user =  User(userID: userID,
                                    firstName: first,
                                    lastName: last,
                                    company: company,
                                    address: address,
                                    position: position,
                                    email: email)

           print(user.position)
       } else {
           print("Document does not exist")
       }
   }
   return user
}

Login Function

//MARK: LOGIN
func login() {
    Auth.auth().signIn(withEmail: emailField.text!, password: passwordField.text!) { (user, error) in
        if error == nil{
            //self.performSegue(withIdentifier: "loginToAdmin", sender: self)

            //Load user
            let loggedOnUser = self.loadUser(userid: Auth.auth().currentUser!.uid)
            print(loggedOnUser.userID)
//                let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
//                let chatViewController = storyBoard.instantiateViewController(withIdentifier: "chatVC") as! UINavigationController
//                self.present(chatViewController, animated: true, completion: nil)
        }
        else {
            DispatchQueue.main.async{
                //Display Alert Message if login failed
                let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
                let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
                alertController.addAction(defaultAction)
                self.present(alertController, animated: true, completion: nil)
            }
        }
    }
}

For the first function, I get a position value, as stated in the print statement. For the second function, my variable, "loggedOnUser" is empty.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
HSCKER_
  • 47
  • 1
  • 1
  • 8
  • getDocument is asynchronous. You cannot return the user that it fetches. – matt Nov 14 '19 at 03:26
  • http://www.programmingios.net/returning-a-value-from-asynchronous-code/ – matt Nov 14 '19 at 03:27
  • note you use `let userid = "56ldZFJiv0dpfaABzo78"` which hides function parameter `userid: String` – Shehata Gamal Nov 14 '19 at 03:32
  • Duplicate of [Returning data from async call in Swift function](https://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function?r=SearchResults&s=1|70.3280) – rmaddy Nov 14 '19 at 05:47

1 Answers1

0

You need a completion as loadUser is asynchronous

func loadUser(userid: String,completion:@escaping(User?) ->()) {
       //print(userid)
       let userid = "56ldZFJiv0dpfaABzo78"
       var user = User()
       let docRef = db.collection("users").document(userid)
       docRef.getDocument { (document, error) in
           if let document = document {
               let first = document.data()!["first"] as! String
               let last = document.data()!["last"] as! String
               let position = document.data()!["position"] as! String
               let company = document.data()!["company"] as! String
               let email = document.data()!["email"] as! String
               let address = document.data()!["address"] as! String
               let userID = document.data()!["userID"] as! String

               //Initalize user
              user =  User(userID: userID,
                                        firstName: first,
                                        lastName: last,
                                        company: company,
                                        address: address,
                                        position: position,
                                        email: email)

               print(user.position)
               completion(user)
           } else {
               print("Document does not exist")
               completion(nil)
           }
       } 
   }

Call

 self.loadUser(userid: Auth.auth().currentUser!.uid) { res in
     if let user = res {
        print(user)
     }
}
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87