簡體   English   中英

Firebase 重新驗證線程 1:致命錯誤:在隱式展開可選值錯誤時意外發現 nil

[英]Firebase Re-Authenticate Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value error

用戶需要重新進行身份驗證才能更改電子郵件地址。 當我編寫以下代碼時,出現錯誤:user.reauthenticate (with: credential) {_ 在錯誤線程 1 的行中:致命錯誤:在隱式展開可選值時意外發現 nil。

var 憑據:AuthCredential! 我也定義了這個

 if let user = Auth.auth().currentUser {
            // re authenticate the user
            user.reauthenticate(with: credential) { _,error in
                if let error = error {
                    print(error)
                } else {
                    // User re-authenticated.
                    user.updateEmail(to: self.emailField.text!) { (error) in

                    }
                }
            }
        }

Xcode 截圖

您需要提示用戶輸入他們的憑據,否則該屬性將為 nil,這將顯示您看到的錯誤

let user = Auth.auth().currentUser
var credential: AuthCredential

// *** Prompt the user to re-provide their sign-in credentials ***
//     populate the credential var with that data so it's not nil
//
user?.reauthenticate(with: credential) { error in
  if let error = error {
    // An error happened.
  } else {
    // User re-authenticated.
  }
}

你可以按照這個例子一步一步

配置:

-> 選擇你的項目

-> 轉到目標

- >選擇你的項目圖標

- >點擊信息標簽

-> 添加新的 URL 類型(來自 GoogleService-Info.plist 的 REVERSED_CLIENT_ID)

1. You need to setup your pre requisite configuration into your AppDelegate class


func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    // Pass device token to auth
    Auth.auth().setAPNSToken(deviceToken, type: AuthAPNSTokenType.unknown)
}

// For iOS 9+
func application(_ application: UIApplication, open url: URL,
                 options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
    if Auth.auth().canHandle(url) {
        return true
    }
    // URL not auth related, developer should handle it.
    return ApplicationDelegate.shared.application(application, open: url, options: options)
}

// For iOS 8-
func application(_ application: UIApplication,
                 open url: URL,
                 sourceApplication: String?,
                 annotation: Any) -> Bool {
    if Auth.auth().canHandle(url) {
        return true
    }
    // URL not auth related, developer should handle it.
    return ApplicationDelegate.shared.application(application, open: url)
}

func application(_ application: UIApplication, didReceiveRemoteNotification notification: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    if Auth.auth().canHandleNotification(notification) {
        completionHandler(UIBackgroundFetchResult.noData)
        return
    }else{
        completionHandler(UIBackgroundFetchResult.newData)
    }
    // This notification is not auth related, developer should handle it.
}


2. It's your ViewModel class


class FirebaseSignin: NSObject {
    public func firebaseSigninWith(phoneNumber: String?, completion: @escaping (Bool, String?, Error?)->()) {
        //SVProgressHUD.show()
        if let phoneNumber = phoneNumber {
            print("firebaseSigninWith phoneNumber: ", phoneNumber)
            Auth.auth().languageCode = "fr";
            PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) { [weak self] (verificationID, error) in
                //SVProgressHUD.dismiss()
                if let error = error {
                    completion(false, verificationID, error)
                    return
                }else{
                    UserDefaults.standard.set(verificationID, forKey: "authVerificationID")
                    completion(true, verificationID, error)
                }
            }
        }else{
            completion(false, nil, nil)
        }
    }

    public func otpConfirmation(verificationCode: String?, completion: @escaping (Bool, Any?, Error?)->()) {
        //SVProgressHUD.show()
        if let verificationCode = verificationCode {
            if let verificationID = UserDefaults.standard.string(forKey: "authVerificationID") {
                let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID, verificationCode: verificationCode)
                Auth.auth().signIn(with: credential) { (authResult, error) in
                    //SVProgressHUD.dismiss()
                    if let error = error {
                        completion(false, verificationID, error)
                        return
                    }else{
                        completion(true, verificationID, error)
                    }
                }
            }else{
                completion(false, nil, nil)
            }
        }else{
            completion(false, nil, nil)
        }
    }
}


3. you call your submitBttonAction function from LoginClass

func submitBttonAction() {
        let mobile_no = mobileNumberTextField.getFormattedPhoneNumber(format: .E164)
        self.firebaseSignin.firebaseSigninWith(phoneNumber: mobile_no) { [weak self] (isSuccess, verificationID, error) in
            if isSuccess {
                //GlobalVariable.showToastWith(view: GlobalVariable.getRootViewController()?.view, message: "OTP send successfully.")
                //RootViewController.selectViewController(_viewController: .OTPConfrimationViewController, ["delegate": self])
                // you open your OTPConfrimationViewController
            }else{
                //GlobalVariable.showToastWith(view: GlobalVariable.getRootViewController()?.view, message: "OTP sending fail \(error?.localizedDescription ?? "")")
            }
        }
    }

4. confirm your OTP from TOPViewController class

func otpConfirmation()  {
    if let otp = self.otpTextField.text {
        self.firebaseSignin.otpConfirmation(verificationCode: otp) { [weak self] (isSuccess, authResult, error) in
            if isSuccess {
                //GlobalVariable.showToastWith(view: GlobalVariable.getRootViewController()?.view, message: "OTP varified successfully.")
                //self?.handleHeaderBackAction(nil)
                //self?.delegate?.otpConfrimationCallBack(isSuccess)
            }else{
                //GlobalVariable.showToastWith(view: GlobalVariable.getRootViewController()?.view, message: "OTP varification fail \(error?.localizedDescription ?? "")")
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM