I'm trying to create an "update email" screen for an iOS app, using Xcode Version 10.2.1 and Firebase. All of the code for updating the email with Firebase works fine, but I'm getting the following error when I try to reauthenticate the user:
Cannot convert value of type '(_) -> ()' to expected argument type 'AuthDataResultCallback?' (aka 'Optional<(Optional, Optional) -> ()>')
Oh, and I'm using Email credentials to Auth users.
I've searched multiple threads here and scoured through the Firebase documentation and can't seem to figure out what is causing this error.
Here's my code, which I pulled from the Firebase Documentation, as well as this thread:
let user = Auth.auth().currentUser
var credential: AuthCredential = EmailAuthProvider.credential(withEmail: "email", password: "pass")
user?.reauthenticate(with: credential) { error in
if let error = error {
// error handled here
} else {
// success
}
}
The error is showing up on the "user?.reauthenticate(with: credential) { error in " line.
Anyone have any idea what is causing this?
(And, apologies if I'm missing something obvious. I'm relatively new to working with Swift/Xcode. )
THANKS!!
I think you're missing the result parameter
let user = Auth.auth().currentUser
var credential: AuthCredential = EmailAuthProvider.credential(withEmail: "email", password: "pass")
user?.reauthenticate(with: credential) { result, error in
if let error = error {
// error handled here
} else {
// success
}
}
where result is an AuthDataResult that contains the result of a successful signin.
Related
So, I tried to add a delete account function using Firebase Manage User service here, it's showing me error. Below is the code.
#IBAction func deleteAccount() {
let user = Auth.auth().currentUser
var credential: AuthCredential
user?.reauthenticate(with: credential) { error in
if let error = error {
self.redAlert(message: "Unable to authenticate. Please try again.")
} else {
Auth.auth().currentUser?.delete { error in
if let error = error {
self.redAlert(message: "An error happened. Please contact support to delete your account")
} else {
self.greenAlert(message: "Your account has been deleted")
}
}
}
}
Attached the screenshot as well.
It keeps showing "Contextual closure type '(AuthDataResult?, Error?) -> Void' expects 2 arguments, but 1 was used in closure body" which I really don't know how to fix it. Would you mind helping to pinpoint this?
Screenshot
EDIT: I actually found the solution. The right code should be:
#IBAction func deleteAccount(_send: Any) {
let user = Auth.auth().currentUser
let emailText: String = email.text!
let passwordText: String = password.text!
var credential: AuthCredential = EmailAuthProvider.credential(withEmail: emailText, password: passwordText)
user?.reauthenticate(with: credential, completion: { (result, error) in
if let error = error {
self.redAlert(message: "Unable to authenticate. Please try again.")
} else {
Auth.auth().currentUser?.delete { error in
if let error = error {
self.redAlert(message: "An error happened. Please contact support to delete your account")
} else {
self.greenAlert(message: "Your account has been deleted")
self.stopLoading()
self.logout()
}
}
}
})
}
Hope it helps anyone that is struggling!
I cannot comment on answers so I have to ask this question, I apologize.
I am getting an error on Xcode when trying to re authenticate the user so their email and or password is changed.
Here is the code I've written.
var credential: AuthCredential
let user = Auth.auth().currentUser
// re authenticate the user
user?.reauthenticate(with: credential) { error in
if let error = error {
// An error happened.
} else {
// User re-authenticated.
}
}
}
I get an error that states Cannot convert value of type '(_) -> ()' to expected argument type 'AuthDataResultCallback?' (aka 'Optional<(Optional, Optional) -> ()>')
It looks like the reauthenticate function returns a tuple, so you have to change the code:
var credential: AuthCredential
let user = Auth.auth().currentUser
// re authenticate the user
user?.reauthenticate(with: credential) { (authDataResult, error) in
if let error = error {
// An error happened.
} else {
// Use `user` property of result to check is successful.
}
}
AuthDataResultCallback
FIRAuthDataResult
I've been looking in the Firebase Documentation and found the method to reauthenticate a user shown below.
let user = Auth.auth().currentUser
var credential: AuthCredential
// Prompt the user to re-provide their sign-in credentials
user?.reauthenticate(with: credential) { error in
if let error = error {
// An error happened.
} else {
// User re-authenticated.
}
}
I get an error and a warning though from the compiler as follows:
Error:
Variable 'credential' used before being initialized
Warning:
'reauthenticate(with:completion:)' is deprecated: Please use
reauthenticateAndRetrieveDataWithCredential:completion: for
Objective-C or
reauthenticateAndRetrieveData(WithCredential:completion:) for Swift
instead.
Has anyone an example of an updated method?
let user = Auth.auth().currentUser
var credential: AuthCredential
user?.reauthenticateAndRetrieveData(with: credential, completion: {(authResult, error) in
if let error = error {
// An error happened.
}else{
// User re-authenticated.
}
})
You are getting error because you haven't initialize credential
You have to initialize AuthCredential first
These credential can vary from
EmailAuthCredential
FacebookAuthCredential
GithubAuthCredential
GoogleAuthCredential
PhoneAuthCredential
PlayGamesAuthCredential
TwitterAuthCredential
Initiziale the variable according to your authentication method e.g.
if you have chosen email you can use like
var credential: AuthCredential = EmailAuthProvider.credential(withEmail: "email", password: "pass")
Auth.auth().signIn(withEmail: emailTextField.text!, password: passwordTextField.text!)
{ (user, error) in
if error != nil {
print(error!)
self.warningLabel.isHidden = false;
self.passwordTextField.text = "";
} else {
print("Log in succesful")
self.performSegue(withIdentifier: "welcomeSeg", sender: self)
}
}
Whenever I sign in or sign up a user I just print a generic warning label instead of the actual issue. I print the error I receive and it's too verbose to show to the user.
Error Domain=FIRAuthErrorDomain Code=17009 "The password is invalid or the user does not have a password." UserInfo={NSLocalizedDescription=The password is invalid or the user does not have a password., error_name=ERROR_WRONG_PASSWORD}
Error Domain=FIRAuthErrorDomain Code=17008 "The email address is badly formatted." UserInfo={NSLocalizedDescription=The email address is badly formatted., error_name=ERROR_INVALID_EMAIL}
Is there any way to fetch the error code so I can be more specific with my error messages? I've looked through the documentation but have been unsuccessful in coming up with anything.
I would recommend creating an AuthErrorCode object (provided by the Firebase SDK) from the error you receive and using that as you see fit. If I remember correctly, AuthErrorCode is an enum with cases like .wrongPassword, .invalidEmail, etc.
A simple pseudocode example:
if error != nil {
if let error = AuthErrorCode(rawValue: error?.code) {
switch error {
case .wrongPassword:
// do some stuff with the error code
}
}
Also, I feel your pain. I've found that the Swift SDK documentation lags quite a bit when changes come along.
I'm developing app with new firebase from google.
And I'm having problem with updating user email and password.
Here's what I've tried.
let currentUser = FIRAuth.auth()?.currentUser
currentUser?.updateEmail(email) { error in
if let error = error {
print(error)
} else {
// Email updated.
currentUser?.updatePassword(password) { error in
if let error = error {
} else {
// Password updated.
print("success")
}
}
}
}
But when updating password this occurs error like this.
"Domain=FIRAuthErrorDomain Code=17014 "This operation is sensitive and requires recent authentication..."
As I know we have to re-configure user after updating email.
I tried with this code for re-cofiguring from the firebase.
let user = FIRAuth.auth()?.currentUser
var credential: FIRAuthCredential
// Prompt the user to re-provide their sign-in credentials
user?.reauthenticateWithCredential(credential) { error in
if let error = error {
// An error happened.
} else {
// User re-authenticated.
}
}
But this occurs error
Variable 'credential' used before being initialed
I know this is because I don't initialize 'credential' variable but I don't know how to fix this to work.
Is there anybody who knows solution?
In your edit you didn't initialize your FIRAuthCredential ... it should be var credential = FIRAuthCredential() or simply use it like below code
let credential = FIREmailPasswordAuthProvider.credentialWithEmail(email, password: password)
user?.reauthenticateWithCredential(credential) { error in
if let error = error {
// An error happened.
} else {
// User re-authenticated.
}
}