3

I checked if user is verified via email or not. However, no matter how many emails I sent and confirm, the verification status is still false. Am I doing something wrong while checking it?

FIRAuth.auth()?.addStateDidChangeListener({ (auth, user) in
            if (auth.currentUser?.isEmailVerified)!{
                let mainStoryboard: UIStoryboard = UIStoryboard(name:"Main",bundle:nil)

                let NewPostViewController: UIViewController = mainStoryboard.instantiateViewController(withIdentifier: "NewPostViewController")

                //Send the user to the LoginViewController
                self.present(NewPostViewController, animated: true, completion: nil)
            }else{
                let alertVC = UIAlertController(title: "Error", message: "Sorry. Your email address has not yet been verified. Do you want us to send another verification email to \(self.currentUser.generalDetails.email).", preferredStyle: .alert)
                let alertActionOkay = UIAlertAction(title: "Okay", style: .default) {
                    (_) in
                    FIRAuth.auth()?.currentUser?.sendEmailVerification(completion: nil)

                }
                let alertActionCancel = UIAlertAction(title: "Cancel", style: .default, handler: nil)
                alertVC.addAction(alertActionOkay)
                alertVC.addAction(alertActionCancel)
                self.present(alertVC, animated: true, completion: nil)
            }
        })
Dravidian
  • 9,945
  • 3
  • 34
  • 74
Tarvo Mäesepp
  • 4,477
  • 3
  • 44
  • 92
  • 1
    Are you reloading your currentUser after you have verified your user? – Dravidian Oct 14 '16 at 05:58
  • How you can reload user? Doesn't terminating app make it? If it is reloading my reputation then why it doesn't detect that the user is verified. – Tarvo Mäesepp Oct 14 '16 at 06:25
  • 2
    The email verified property is only reloaded when the user signs in. If I recall correctly you can [re-authenticate](https://firebase.google.com/docs/reference/ios/firebaseauth/interface_f_i_r_user#afa881b98220684503c5141afbb60e83d) to get the updated value, but [`reloadWithCompletion`](https://firebase.google.com/docs/reference/ios/firebaseauth/interface_f_i_r_user#ac9a4e0578dcbe4abee62143fa2b25f66) also sounds promising. – Frank van Puffelen Oct 14 '16 at 06:57
  • Also see http://stackoverflow.com/questions/37900447/user-emailverified-doesnt-change-after-clicking-email-verification-link-firebas – Frank van Puffelen Oct 14 '16 at 07:01
  • Thanks. Got it working :) I even didn't think about it that something like this has to be done. I thought that Firebase adds some mark to the user or it will be totally different because documentation is pretty bad about this. Even if I try to find those values by my self I can't find them if I go to the documentation :D Learning new things every day. – Tarvo Mäesepp Oct 14 '16 at 09:30

2 Answers2

10

How i implemented this feature was to add a NSTimer, with time interval which would check if the user has been verified and then terminate the timer when the verification was done.

var verificationTimer : Timer = Timer()    // Timer's  Global declaration

self.verificationTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(LoginViewController.checkIfTheEmailIsVerified) , userInfo: nil, repeats: true)

Function to check your current user state:-

func checkIfTheEmailIsVerified(){

    FIRAuth.auth()?.currentUser?.reload(completion: { (err) in
        if err == nil{

            if FIRAuth.auth()!.currentUser!.isEmailVerified{

                let feedVCScene = self.navigationController?.storyboard?.instantiateViewController(withIdentifier: "ViewControllerVC_ID") as! ViewController
                self.verificationTimer.invalidate()     //Kill the timer
                self.navigationController?.pushViewController(feedVCScene, animated: true)
                // Segueing to the next view(i prefer the instantiation method).
            } else {

                print("It aint verified yet")

            }
        } else {

            print(err?.localizedDescription)

        }
    })

}
Dravidian
  • 9,945
  • 3
  • 34
  • 74
  • Woww.. It is really working, awesome solution :). However should I save the value into somewhere so I do not have to run the function every time I click some button? Anyways, thank you so much :) – Tarvo Mäesepp Oct 14 '16 at 09:28
  • No `reload` and `FIRAuth.auth()!.currentUser!.isEmailVerified` will take of that for you – Dravidian Oct 14 '16 at 09:36
1

My way to do it was to add a NSNotification.Name.UIApplicationDidBecomeActive because the user had to leave the app to verify the email:

NotificationCenter.default.addObserver(self,selector:#selector(APEmailVerificationViewController.checkEmailVerificationState),name:NSNotification.Name.UIApplicationDidBecomeActive, object:  nil)

Do not forget to remove the notification in viewDidDisappear. This is the APEmailVerificationViewController.checkEmailVerificationState func:

FIRAuth.auth()?.currentUser?.reload(completion: { [unowned self] (error) in
        if error != nil {
            print(error!.localizedDescription)
            return
        }
        if !FIRAuth.auth()!.currentUser!.isEmailVerified {
            return
        }

        /**
            Great! We go the playground of the app.
         */
        UIAlertView(title: "Hooray", message: "You've successfully verified your email", delegate: nil, cancelButtonTitle: "Ok").show()
        APIntent.gotoPlayground()
    })

Hope it helps!

Paul Razvan Berg
  • 16,949
  • 9
  • 76
  • 114