0

This code is currently in a View Controller for a login handler using Firebase. A string is written to a realtime database and the retrieveUserType function reads this data. Currently when trying to print the userType after the IBAction for the login button is pressed the value of the variable remains a blank string.

var userType:String = ""

func retrieveUserType(){

    let userTypeDB = Database.database().reference()
    let currentUser = "kLxqZteRfBeC0bNIkLCjrPukMGx1"


 userTypeDB.child("UserType").child(currentUser).observeSingleEvent(of: .value, with: {
        (snapshot) in
        // Get user value
        let value = snapshot.value as? NSDictionary
        let email = value?["Email"] as? String ?? ""
        self.userType = value?["User Type"] as? String ?? ""

        print(email)
    }){
        (error) in
        print(error.localizedDescription)
    }
}

@IBAction func loginButtonPressed(_ sender: Any) {

    retrieveUserType()
    if userType != "Student"{
        print("error")
    } else {
        print("success")
    }
  • 1
    You are missing the fact that the FireBase method is asynchone. `self.userType = value?["User Type"] as? String ?? ""` is called AFTER `if userType != "Student"{`. You can add logs if you want, you'll see. Look for "Closure + Swift + Async" to look how to manage that. – Larme Sep 30 '18 at 15:27

1 Answers1

1

Larme is correct. Your retrieveUserType function is asynchronous. Meaning you do not know exactly when it will be completed. So you need a completion block to handle the userType variable. Like so:

typealias RetrieveUserCompletionBlock = ((_ userType: String) -> Void)
func retrieveUserType(withBlock completion: @escaping RetrieveUserCompletionBlock){

    let userTypeDB = Database.database().reference()
    let currentUser = "kLxqZteRfBeC0bNIkLCjrPukMGx1"


    userTypeDB.child("UserType").child(currentUser).observeSingleEvent(of: .value, with: {
        (snapshot) in
        // Get user value
        let value = snapshot.value as? NSDictionary
        let email = value?["Email"] as? String ?? ""
        completion(value?["User Type"] as? String ?? "")

        print(email)
    }){
        (error) in
        completion("default value") // or ""
        print(error.localizedDescription)
    }
}

As you can see, we have RetrieveUserCompletionBlock, which is just atypealias. From this completion block, we would get theuserType``` properly.

How to call this new asynchronous function? Here:

retrieveUserType { (userType) in
    if userType != "Student"{
        print("error")
    } else {
        print("success")
    }
}

This should help you out :)

Glenn Posadas
  • 12,555
  • 6
  • 54
  • 95