需要再次验证用户才能更改电子邮件地址。当我编写以下代码时,出现错误:user.reauthenticatecate(with:credential){_在错误行中线程1:致命错误:意外地发现nil,同时隐式展开了Optional值。
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
}
}
}
}
答案 0 :(得分:1)
您需要提示用户输入其凭据,否则该属性将为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.
}
}
答案 1 :(得分:0)
您可以逐步遵循此示例
配置:
->选择您的项目
->转到目标
->选择项目图标
->点击“信息”标签
->添加新的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 ?? "")")
}
}
}
}