How To Fetch Error Code From Firebase? - swift

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.

Related

Firebase with Swift, sendSignInLinkToEmail succeeds with email not registered

I'm implementing sign-in via email link and I have it sending the email, but I'm using an email that has not been registered yet. Is there a way to detect if the email is already registered before calling sendSignInLinkToEmail? No error was reported from the call. TIA!
Nabil's answer led me to finding the function fetchSignInMethods, which was just the thing I needed. Posted here for anyone else looking for this.
Auth.auth().fetchSignInMethods(forEmail: email, completion: {
methods, error in
if methods == nil {
self.showAlert(title: "This email is not registered, please create an account")
return
}
})
Maybe this function can help you
Auth.auth().fetchProviders(forEmail: emailAddress, completion: {
error in
if let error = error {
print(error.localizedDescription)
} else {
//
}
})
So that if the email doesn't exist it'll return an error otherwise you can run the sendSignInLinkToEmail function

How to detect and handle firebase Permission Denied error code with swift

I am getting the following error while observe data from firebase realtime database. What I want to do is if the error is Permission Denied, I want to do a different action. How can I tell if the error is Permission Denied?
error :
Optional(Error Domain=com.firebase Code=1 "Permission Denied" UserInfo={NSLocalizedDescription=Permission Denied})
mycode:
func observeData(completion: #escaping (Bool) -> Void){
Database.database().reference().child("values").observe(.value, with: { (snap) in
completion(true)
}){ (error) in
let errorCode = (error as NSError).code
if errorCode == .?????? { //-->> what to come here
self.anotherFunc() //--> if Permission Denied call this func
completion(false)
}else{
completion(true)
}
}
}
This is what I did for Auth errors in my firebase app. Not sure if it will work in your context, but you might find it useful.
func firebaseErrorParser(error: Error) -> String? {
if let errorCode = AuthErrorCode(rawValue: error._code) { // <- here!!
switch errorCode { // switch case
case .invalidVerificationCode:
return "Wrong code or phone number!"
default:
return "An error occured... "
}
} else {
return nil
}
}
I only had one entry in my switch/case because the only error I wanted to give specific feedback to the user about was if the user entered the wrong phone number. It seems like you can do something similar with firestore permissions errors

Swift 5 & Firebase: Creating a shared sign in and sign-out button

I thought I'd return to StackOverflow with another question because you guys helped me significantly with my last issue
Anyway, I currently have my authentication system setup so that the sign in and signup button are shared. I am looking to have firebase reference storage when an email is entered to have it checked against other accounts in the database. As of right now, a user can enter an email address for their account and then if they enter the wrong password it just sends them right to the sign up even though they currently have an account. This is a serious problem as it will cause confusion
I want it to work like so:
If the email address is taken, I want an alert to be displayed for the user says "Incorrect password"
If the email address is not taken, I want it to tell the user that they need to enter a password with at least 10 characters, 1 number, and 1 special character, which I have already figured out using
I only want it to segue to create a new user if the email is not taken and the password and email field meet the criteria fields that I have already set within my code. I just need help preventing it from switching to the create new user VC if the email is already taken, and I need to to say
func isValidPassword(_ email: String) -> Bool {
let emailRegEx = "##$%^&+=^.*(?=.{10,})(?=.*d)(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$"
let emailPred = NSPredicate(format:"SELF MATCHES %#", emailRegEx)
return emailPred.evaluate(with: email)
}
Anyway, here is the code so far attached to the IBAction
if let email = emailField.text, let password = passwordField.text {
Auth.auth().signIn(withEmail: email, password: password, completion:
{ (user,error) in
if error == nil {
if let user = user {
self.userUid = user.user.uid
self.goToFeedVC()
}
} else {
self.goToCreateUserVC()
Here is a picture of the interface
I want it to be intuitive but I have been unable to code this myself so if anyone is able to help advise me on how to finish this block it would be incredibly appreciated
Firebase gives pretty detailed error responses for their Auth call:
So you can check to see what the error is inside of your call:
Below are the two error that they give (I only added the two scenarios that you mentioned)
Description: The password is invalid or the user does not have a password.
FIRAuthErrorUserInfoNameKey: ERROR_WRONG_PASSWORD
&
There is no user record corresponding to this identifier. The user may have been deleted.
FIRAuthErrorUserInfoNameKey: ERROR_USER_NOT_FOUND
Auth.auth().signIn(withEmail: email, password: password, completion:
{ (user,error) in
if error == nil {
if let user = user {
self.userUid = user.user.uid
self.goToFeedVC()
}
} else {
guard let error = error?.localizedDescription else { return } // but actually handle this
print(error)
if error == wrong password {
// show alert for email taken/wrong password
} else if error == user doesnt exists {
// self.goToCreateUserVC()
}
}
}
Just replace the if and else if conditions with the actual errors. I'd avoid comparing the strings and use the key/code in case the strings change in the future.
Official list of error codes can be found here
And if you print the full error instead of the error?.localizedDescription you'll get the full details, as can be seen here:
Optional(Error Domain=FIRAuthErrorDomain Code=17011 "There is no user record corresponding to this identifier. The user may have been deleted." UserInfo={NSLocalizedDescription=There is no user record corresponding to this identifier. The user may have been deleted., FIRAuthErrorUserInfoNameKey=ERROR_USER_NOT_FOUND})

How to fix an uid error when it can't find it in the code

I'm setting up an anonymous user login using firebase and I typed in my code but when trying to run the app an error message comes up saying:
Value of type 'AuthDataResult' has no member 'uid'
is there a way to fix this solution?
Auth.auth().signInAnonymously(completion: { ( User, error) in
if error == nil{
print("UserId: \(User!.uid)")
}else{
print(error!.localizedDescription)
}
})

I'm having trouble resetting passwords with Parse

I am making my own app in Swift, and wanted to include the feature of resetting passwords using Parse. My console eventually shows a successful notice, but when I go to the email to see if Parse sent the email to reset password, I don't receive anything. Would really appreciate it if you could help me sort this issue :D I've added a screenshot so that you can see what my console shows.
#IBAction func recoverPasswordButton(_ sender: Any) {
PFUser.requestPasswordResetForEmail(inBackground: emailTextField.text!, block: { (success, error) in
if self.emailTextField != nil {
self.displayAlert(title: "Check your email", message: "A link has been sent to recover your password. Follow the instructions.")
print("A link to recover your password has been sent")
} else {
var errorText = "Unknown error: please try again"
if let error = error {
errorText = error.localizedDescription
}
self.displayAlert(title: "Email is not valid", message: errorText)
}
})
}
For Email verification, You need to add the setting in the dashboard like below
The first thing is that Parse stops his support, you have to use Back4App.