Tawfeeq
Tawfeeq

Reputation: 13

Firebase authentication not being called and returns a null user (Swift)

I've just started to learn swift 3 and I came from .NET background. I am having trouble authenticating users using firebase with my application. I was trying to create a general function which in turns call another Firebase function.



    let user = logIn(email: email, password: password)
    if user != nil{
         self.navigationController?.pushViewController(MainVC(), animated:   true)
    }

 

    func logIn(email: String,password: String) -> Firebase.User? {
            var loginUser:Firebase.User?

            Auth.auth().signIn(withEmail: email, password: password) { (user, error) in
                if(error != nil){
                    print(error!)
                    return
                }


                if let firebaseUser = user {
                    loginUser = firebaseUser
                }
            }
            if let user = loginUser{
                return user
            }
            else {
                return nil
            }
        }

During my debugging, I found the Auth.auth().signIn function skipped and not been executed by some how and returns null. however, when I run the application again, I found the firebase authenticate my user!!!

Upvotes: 0

Views: 1101

Answers (1)

ZassX
ZassX

Reputation: 1369

The problem is that signIn is async function, which takes some time to execute. That means that when you call your logIn function, before signIn is able to sign you in, your else { return nil} executes and the returned value is nil.

You shouldn't return from this function, what you should do instead is use a callback: So replace your function header with this.

func logIn(email: String,password: String, callback: @escaping (Firebase.User?) -> ()) {

Remove the last if in your function because you don't need it, everything will be handled in the signInblock.

Replace the code inside signIn block with:

if error != nil {
  print(error!)
  callback(nil)
}

if let firebaseUser = user {
  callback(firebaseUser)
}

Now you have to change the way you are calling your logIn function into:

logIn(email: yourEmail, password: yourPassword) { (firebaseUser: Firebase.User?) in
  // Your result is saved in firebaseUser variable
}

Whole code together

// CALL LOGIN FUNCTION

logIn(email: yourEmail, password: yourPassword) { (firebaseUser: Firebase.User?) in
  // Your result is saved in firebaseUser variable
  if firebaseUser != nil{
    self.navigationController?.pushViewController(MainVC(), animated:   true)
  }

}

// LOGIN FUNCTION

func logIn(email: String,password: String, callbacK: @escaping (Firebase.User?) -> ()) {
  Auth.auth().signIn(withEmail: email, password: password) { (user, error) in
    if error != nil {
      print(error!)
      callback(nil)
    }

    callback(firebaseUser)
  }
}

I haven't tested this so maybe you will have to make some small modifications but this is the right way of doing it. I hope you get the idea.

Upvotes: 1

Related Questions