前提・実現したいこと
Swiftにおいて、FirebaseAuthenticationのメールアドレスで確認メールのリンクを踏んだユーザーのみ、次の画面に遷移できるようにしたい。
現在の状況
ユーザー名、メールアドレス、パスワードを入力した後に、新規登録ボタンを押すと、画面が遷移する。
その遷移した画面先で確認メールのリンクを踏んだユーザーが、本登録完了ボタンを押すと更に次の画面に遷移できるようにしたいが、それが実現していない。
確認メール自体は、新規登録ボタンを押すと届く。
ちなみにログイン画面も用意してあり、確認メールを踏んだユーザーしか、ログインできないようにしていますが、そちらは上手く機能しています。(新規登録後、本登録完了ボタンが押せないので、一度アプリを閉じて再起動した後にログインした場合)
発生している問題・エラーメッセージ
Firebaseから届いたメールのリンクを踏んでもAuth.auth().currentUser?.isEmailVerifiedがtrue にならず、falseのままになってしまう。 そのため、最後の画面に遷移することができない。
該当のソースコード
新規登録の2番目の画面のコードです。
swift
1import UIKit 2import Firebase 3 4class ProvisionalRegistrationViewController: UIViewController { 5 6 var alertController = UIAlertController() 7 var flag : Bool? 8 var flag2 : Bool? 9 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 14 Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.conformOfOfficialRegistration), userInfo: nil, repeats: true) 15 16 17 } 18 19 override func viewWillAppear(_ animated: Bool) { 20 super.viewWillAppear(animated) 21 22 23 24 Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.conformOfOfficialRegistration), userInfo: nil, repeats: true) 25 } 26 27 @objc func conformOfOfficialRegistration() -> Bool { 28 29 flag = Auth.auth().currentUser?.isEmailVerified 30 Auth.auth().addStateDidChangeListener({ (auth, user) in 31 self.flag2 = user?.isEmailVerified 32 print(self.flag2 as Any) 33 34 }) 35 print(flag as Any) 36 return flag! 37 38 } 39 40 @IBAction func sendEmailButton(_ sender: Any) { 41 42 Auth.auth().currentUser?.sendEmailVerification(completion: { (error) in 43 if error == nil { 44 45 self.showAlert(title: "メッセージ", message: "メールを送信しました") 46 47 } else { 48 49 self.showErrorIfNeeded(error) 50 51 } 52 }) 53 54 } 55 56 @IBAction func OfficialRegistrationButton(_ sender: Any) { 57 58 59 print(Auth.auth().currentUser?.isEmailVerified as Any) 60 print(Auth.auth().currentUser as Any) 61 print(Auth.auth().currentUser?.displayName as Any) 62 print(Auth.auth().currentUser?.email as Any) 63 print(Auth.auth().currentUser!.isEmailVerified) 64 print(Auth.auth().currentUser!) 65 66 if flag == true { 67 68 performSegue(withIdentifier: "officialRegistration", sender: nil) 69 70 } else { 71 72 showAlert(title: "メッセージ", message: "本登録が完了していません") 73 74 } 75 76 77 } 78 79 func showAlert(title: String, message: String) { 80 81 alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) 82 alertController.addAction(UIAlertAction(title: "ok", style: .default, handler: nil)) 83 84 present(alertController, animated: true, completion: nil) 85 86 87 } 88 89 private func showErrorIfNeeded(_ errorOrNil: Error?) { 90 // エラーがなければ何もしません 91 guard let error = errorOrNil else { return } 92 93 let message = errorMessage(of: error) // エラーメッセージを取得 94 let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert) 95 alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) 96 present(alert, animated: true, completion: nil) 97 } 98 99 private func errorMessage(of error: Error) -> String { 100 var message = "エラーが発生しました" 101 guard let errcd = AuthErrorCode(rawValue: (error as NSError).code) else { 102 return message 103 } 104 105 switch errcd { 106 case .networkError: message = "ネットワークに接続できません" 107 case .userNotFound: message = "ユーザが見つかりません" 108 case .invalidEmail: message = "不正なメールアドレスです" 109 case .emailAlreadyInUse: message = "このメールアドレスは既に使われています" 110 case .wrongPassword: message = "入力した認証情報でサインインできません" 111 case .userDisabled: message = "このアカウントは無効です" 112 case .weakPassword: message = "パスワードが脆弱すぎます" 113 // これは一例です。必要に応じて増減させてください 114 default: break 115 } 116 return message 117 } 118 119}
ソースコードの説明
@objc func conformOfOfficialRegistration() -> Bool { flag = Auth.auth().currentUser?.isEmailVerified Auth.auth().addStateDidChangeListener({ (auth, user) in self.flag2 = user?.isEmailVerified print(self.flag2 as Any) }) print(flag as Any) return flag! }
でサインアップしたユーザーのisEmailVerifiedが、trueになっているかfalseのままか確認している。
override func viewDidLoad() { super.viewDidLoad() Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.conformOfOfficialRegistration), userInfo: nil, repeats: true) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.conformOfOfficialRegistration), userInfo: nil, repeats: true) }
でconformOfOfficialRegistration()を1秒毎に実行している。
@IBAction func sendEmailButton(_ sender: Any) { Auth.auth().currentUser?.sendEmailVerification(completion: { (error) in if error == nil { self.showAlert(title: "メッセージ", message: "メールを送信しました") } else { self.showErrorIfNeeded(error) } }) }
はメールの再送信。(再送信できていた)
@IBAction func OfficialRegistrationButton(_ sender: Any) { print(Auth.auth().currentUser?.isEmailVerified as Any) print(Auth.auth().currentUser as Any) print(Auth.auth().currentUser?.displayName as Any) print(Auth.auth().currentUser?.email as Any) print(Auth.auth().currentUser!.isEmailVerified) print(Auth.auth().currentUser!) if flag == true { performSegue(withIdentifier: "officialRegistration", sender: nil) } else { showAlert(title: "メッセージ", message: "本登録が完了していません") } }
で確認メールのリンクを踏んだユーザーのみが、最後の画面に遷移できるようにしている。
試したこと
Timer..scheduledTimerメソッドを使って、確認メールを踏んだか否かを常に確認するようにしているが、確認メールを踏んだ後もfalseになってしまった。
補足情報(FW/ツールのバージョンなど)
xcode11.3.1

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/01/27 15:04