How To Check If An Email Address Is Already In Use Firebase
Asked Answered
S

2

3

working on some FirAuth things, but for some reason I can't figure out how to check if the users proposed email address has already been taken. I've tried calling .fetchProvidersForEmail as suggested in other questions from a while back, but for whatever reason it just won't work. Also, I'm very green when it comes to completion handlers, so any constructive criticism on that would be welcome as well. So, for now, the parts of my code that pertain to this are:

import UIKit
import Firebase
class LoginViewController: UIViewController {
var reply : Bool = true
@IBOutlet weak var emailTxt: UITextField!

@IBAction func nextScreen(sender: UIButton) {
print(emailCheck(emailTxt.text!))
}

 func emailCheck(input : String)->Bool{
    let pullEmails = FIRAuth.auth()!.fetchProvidersForEmail(input, completion:{
        result,error in
        var decision : Bool = true
        if error == "nil" {
            print(error)
            self.reply = true
        }else{
            print(error)
            self.reply = false
        }
    })
    return reply
}
}

So what happens with this is that reply always prints true, probably because I explicitly defined it to at the top. Either way, it is almost as if the completion handler isn't waiting to actually be completed before it returns the value. I've tried to figure out how to use them, as well as AsyncTasks, but I was wondering if there was a simple error I've made in here that could solve this. Thanks everybody!

Scarberry answered 30/7, 2016 at 17:43 Comment(0)
S
8

This answer took my quite a long time to find, but here it is.

func emailCheck(input: String, callback: (isValid: Bool) -> Void) {
    FIRAuth.auth()?.signInWithEmail(input, password: " ") { (user, error) in
        var canRegister = false

        if error != nil {
            if (error?.code == 17009) {
                canRegister = false
            } else if(error?.code == 17011) {
                //email doesn't exist
                canRegister = true
            }
        }

        callback(isValid: canRegister)
    }
}

The reason why this code works is pretty simple. Essentially if you pass a non null password into Firebase, i.e. " " instead of "" you will get some sort of error code back. The two most important return codes that I am looking for is 17009 and 17011. This is because if 17009 is returned (signifying a wrong password) then we know that there already is an email address associated with that proposed address, so therefore the user shouldn't be able to sign up for a new one. The next code, 17011 is pretty straight forward. It means that there is no user on file with that given email address, which ten allows the user to claim it. I call this function by using this:

mailCheck(emailTxt.text!) { isValid in
                if isValid {
                    print("valid")
                } else {
                    print("Invalid!")
                }

And then manage the boolean that comes from it. Hope this helps other people in the same situation!

Scarberry answered 31/7, 2016 at 14:55 Comment(1)
Thank you for posting this! It's ugly, but there needs to be a way to accomplish this /somehow/. I appreciate you sharing!Spangler
A
9

I tried the .fetchProviders(forEmail: String, completion: FIRProviderQueryCallback?) and if provided a valid email address in Firebase it will return its password in a [String]?. If there is a password you know there is an active account:

   FIRAuth.auth()?.fetchProviders(forEmail: email, completion: { (stringArray, error) in
            if error != nil {
                print(error!)
            } else {
                if stringArray == nil {
                    print("No password. No active account")
                } else {
                    print("There is an active account")
                }
            }
        })

This is a little less of a hack but I haven't found anything better. Disclosure: I'm only using password authentication

If you're creating a user or logging in you'll receive a .emailAlreadyInUse error from the callback. Here is the list of all possible errors thrown by Auth.

Anthropomorphism answered 28/2, 2017 at 19:22 Comment(0)
S
8

This answer took my quite a long time to find, but here it is.

func emailCheck(input: String, callback: (isValid: Bool) -> Void) {
    FIRAuth.auth()?.signInWithEmail(input, password: " ") { (user, error) in
        var canRegister = false

        if error != nil {
            if (error?.code == 17009) {
                canRegister = false
            } else if(error?.code == 17011) {
                //email doesn't exist
                canRegister = true
            }
        }

        callback(isValid: canRegister)
    }
}

The reason why this code works is pretty simple. Essentially if you pass a non null password into Firebase, i.e. " " instead of "" you will get some sort of error code back. The two most important return codes that I am looking for is 17009 and 17011. This is because if 17009 is returned (signifying a wrong password) then we know that there already is an email address associated with that proposed address, so therefore the user shouldn't be able to sign up for a new one. The next code, 17011 is pretty straight forward. It means that there is no user on file with that given email address, which ten allows the user to claim it. I call this function by using this:

mailCheck(emailTxt.text!) { isValid in
                if isValid {
                    print("valid")
                } else {
                    print("Invalid!")
                }

And then manage the boolean that comes from it. Hope this helps other people in the same situation!

Scarberry answered 31/7, 2016 at 14:55 Comment(1)
Thank you for posting this! It's ugly, but there needs to be a way to accomplish this /somehow/. I appreciate you sharing!Spangler

© 2022 - 2024 — McMap. All rights reserved.