Trouble implementing UIAlertController. Cant get alert to show up - ios

I have set an alert to be shown as any error occurs when some user tries to request a new password through firebase, but it is not working.
The print("problems with email field") is being printed so I believe I have made something wrong when writing the alert part.
#IBAction func recuperarSenha(_ sender: Any) {
Auth.auth().sendPasswordReset(withEmail: self.loginTextView.text!) { error in
if error != nil {
print("problems with email field")
let alert = UIAlertController(title: "Couldn't send recover message", message: "Check if e-mail field is properly filled.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK!", style: .default, handler: nil))
}
}
}

You need to present your alert after creating it. Add the following code after adding action:
self.present(alert, animated: true, completion: nil)
Edited version of your code:
#IBAction func recuperarSenha(_ sender: Any) {
Auth.auth().sendPasswordReset(withEmail: self.loginTextView.text!) { error in
if error != nil {
print("problems with email field")
let alert = UIAlertController(title: "Couldn't send recover message", message: "Check if e-mail field is properly filled.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK!", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
}

Related

receiving error message "the email address is already in use by another account" when attempting to register with new email

I have a register page with 3 UITextFields and a register button. When the button is clicked, the account is supposed to be registered to my Firebase Database. However, whenever I click the button, the SVProgressHUD.showSuccess() appears, but so does an UIAlert saying "the email address is already in use by another account" in addition to the preformSegue not occurring. This error cannot be true though because none of the emails I am using are registered to my app.
Below is the code I currently am using:
func register() {
Auth.auth().createUser(withEmail: registerEmail.text!, password: registerPassword.text!) { (user, error) in
if error == nil {
SVProgressHUD.dismiss()
SVProgressHUD.showSuccess(withStatus: "Welcome \(self.registerEmail.text!)")
self.performSegue(withIdentifier: "goToTheHome", sender: self)
}
else {
SVProgressHUD.dismiss()
print(error as Any)
print("")
let alert = UIAlertController(title: "Error", message: error!.localizedDescription, preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert,animated: true) }
}
}
#IBAction func createAccount(_ sender: UIButton) {
SVProgressHUD.show()
if registerPassword.text == confirmPassword.text {
register()
}
else {
SVProgressHUD.dismiss()
let alert = UIAlertController(title: "Error", message: "Passwords do not match", preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert,animated: true)
}
}
If the new account was successfully created, the user is signed in, and you can get the user's account data from the result object that's passed to the callback method.
You can try to check your user (result) object in the console..

Firebase Reset Password IOS App xcode

I'm currently developing an app that has a login page with a login button and main menu button. I've created everything and is working pretty well for the time being. I'm using Firebase as my backend database.
I wanted to create a 'forgot password' button which i already did and seems like its working but the only problem is it doesn't give me an alert when it sends the email, it just sends it, but i get the alert when i enter an email which is not in the user authentication. Below is my code for the forget password button:
#IBAction func frgtpassTapped(_ sender: Any) {
Auth.auth().sendPasswordReset(withEmail: emailTextField.text!) { error in
if self.emailTextField.text?.isEmpty==true{
let resetFailedAlert = UIAlertController(title: "Reset Failed", message: "Error: \(String(describing: error?.localizedDescription))", preferredStyle: .alert)
resetFailedAlert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(resetFailedAlert, animated: true, completion: nil)
}
if error != nil && self.emailTextField.text?.isEmpty==false{
let resetEmailAlertSent = UIAlertController(title: "Reset Email Sent", message: "Reset email has been sent to your login email, please follow the instructions in the mail to reset your password", preferredStyle: .alert)
resetEmailAlertSent.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(resetEmailAlertSent, animated: true, completion: nil)
}
}
}
I accept if anyone downvotes this post but please if you do, comment below the reason. Any help would be much appreciated!
Please this code
Auth.auth().sendPasswordReset(withEmail: emailTextField.text!) { error in
DispatchQueue.main.async {
if self.emailTextField.text?.isEmpty==true || error != nil {
let resetFailedAlert = UIAlertController(title: "Reset Failed", message: "Error: \(String(describing: error?.localizedDescription))", preferredStyle: .alert)
resetFailedAlert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(resetFailedAlert, animated: true, completion: nil)
}
if error == nil && self.emailTextField.text?.isEmpty==false{
let resetEmailAlertSent = UIAlertController(title: "Reset Email Sent", message: "Reset email has been sent to your login email, please follow the instructions in the mail to reset your password", preferredStyle: .alert)
resetEmailAlertSent.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(resetEmailAlertSent, animated: true, completion: nil)
}
}
}
It is clear from your code, that you are passing the unWrapped value to the closure, so the textField must contains some value in it.
THIS LINE IN YOUR CODE: if self.emailTextField.text?.isEmpty==true {
will never be entered inside condition.
It should be updated to like:
#IBAction func frgtpassTapped(_ sender: Any) {
//BEFORE SENDING DATA FOR AUTHENTICATION, CHECK FOR THE isEmpty CONDITIONS HERE
Auth.auth().sendPasswordReset(withEmail: emailTextField.text!) { error in
DispatchQueue.main.async {
if error != nil {
// YOUR ERROR CODE
} else {
//YOUR SUCCESS MESSAGE
}
}
}
}

segue performed before the UIAlertController in swift

I have just coded a signup page in which if user does not enter text in any of the uitextfield then it should receive an error message (UIAlert) ; else (if user enter text in all uitextfield) signup page will present for Firebase Authentication.
in my code, user will direct to sign-in page only if authentication successfully complete else it should remain in signup page with alert message.
Problem - my code is able to produce alert message but same time it is taking user to sign-in page automatically even when there is an error. which means it is performing a segue that takes user to sign-in page i.e. segue unwinding irrespective of alert message.
can anyone help me why this may be happening?
#IBAction func registerPressed(_ sender: Any) {
if nameText.text!.isEmpty || genderText.text!.isEmpty || countryText.text!.isEmpty || yourSchool.text!.isEmpty || yourClass.text!.isEmpty {
print("Please fill all fields") //my code is printing this error
//alert message popup - my code is ble to produce this alert but same it is performing segue and taking user to signin page
//ideally, i want user to be in signup page unless all criteria meet
let alertController = UIAlertController(title: "Error", message: "Please fill all fields", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action:UIAlertAction) in
print("Okay")
}))
let alertWindow = UIWindow(frame: UIScreen.main.bounds)
alertWindow.rootViewController = UIViewController()
alertWindow.windowLevel = UIWindowLevelAlert
alertWindow.makeKeyAndVisible()
alertWindow.rootViewController?.present(alertController, animated: true, completion: nil)
}
else {
Auth.auth().createUser(withEmail: yourEmail.text!, password: yourPassword.text!) { (user, error) in
if error != nil {
///print errror message
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action:UIAlertAction) in
print("Okay")
}))
let alertWindow = UIWindow(frame: UIScreen.main.bounds)
alertWindow.rootViewController = UIViewController()
alertWindow.windowLevel = UIWindowLevelAlert + 1;
alertWindow.makeKeyAndVisible()
alertWindow.rootViewController?.present(alertController, animated: true, completion: nil)
}
else {
print("You have successfully signed up")
self.performSegue(withIdentifier: "JoinUs2SignPage", sender: self)
//updating user information
let userID = Auth.auth().currentUser!.uid
let usertype: String = "Student"
self.ref.child("users").child(userID).setValue(["usertype": usertype ,"username": self.nameText.text!, "usergender": self.genderText.text!, "usercountry": self.countryText.text!, "userschool": self.yourSchool.text!, "userclass": self.yourClass.text!,])
}
}
}
}
From this bit of code it doesn't really look like anything is wrong. However, you should block the UI while Auth.auth().createUser(...) is running. Otherwise there's a chance that you call registerPressed with everything correct, but then delete the text from a label and call it again before the callback. That way you have an alert and then the segue is called.
You're also doing something quite crazy with the way that you're presenting your alerts. Instead of creating a new window, adding to it a view controller and all that jazz, just call self.present(alertController, animated: true). E.g.
let alertController = UIAlertController(title: "Error", message: "Please fill all fields", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action:UIAlertAction) in
print("Okay")
}))
self.present(alertController, animated: true)
Remove the segue and push to destination view controller programmatically.
self.navigationController?.pushViewController(destinationVC, animated: true)
I was doing a silly mistake where I created the segue directly on IBAction and hence whenever I was pressing the button it was performing the segue irrespective UIAlerts. my updated code is below :
#IBAction func registerPressed(_ sender: Any) {
if nameText.text!.isEmpty || genderText.text!.isEmpty || countryText.text!.isEmpty || yourSchool.text!.isEmpty || yourClass.text!.isEmpty {
//alert message popup
let alertController = UIAlertController(title: "Error", message: "Please fill all fields", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action:UIAlertAction) in
print("Okay")
}))
self.present(alertController, animated: true, completion: nil)
}
else {
Auth.auth().createUser(withEmail: yourEmail.text!, password: yourPassword.text!) { (user, error) in
if error != nil {
///print errror message
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action:UIAlertAction) in
print("Okay")
}))
self.present(alertController, animated: true, completion: nil)
}
else {
let alertController = UIAlertController(title: "Congratulation", message: "You have successfully signed up", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Get Started", style: .default, handler: { (action:UIAlertAction) in
self.performSegue(withIdentifier: "back2SignPage", sender: self)
}))
self.present(alertController, animated: true, completion: nil)
//updating user information
let userID = Auth.auth().currentUser!.uid
let usertype: String = "Student"
self.ref.child("users").child(userID).setValue(["usertype": usertype ,"username": self.nameText.text!, "usergender": self.genderText.text!, "usercountry": self.countryText.text!, "userschool": self.yourSchool.text!, "userclass": self.yourClass.text!,])
}
}
}
}

Segue after new user creation using firebase not being performed -Swift

I am having issues with two segues however, since I used the same logic in the implementation of each of these segues I'm going to go ahead and condense everything into one question. Basically, I am trying to initialize a segue after performing createUser function with firebase and after performing login function also handled by Firebase, however, when the SignUp and Login buttons are clicked there seems to be no response to the segue being called. Below is the code for each of the #IBActions
#IBAction func signUpComplete(_ sender: Any) {
FIRAuth.auth()?.createUser(withEmail: signUpEmailField.text!, password: signUpPasswordField.text!, completion: { (user: FIRUser?, error) in
if self.signUpEmailField.text == "" || self.signUpPasswordField.text == "" {
let alert = UIAlertController(title: "Oops!", message: "A valid E-mail and Password are Required", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
if FIRAuthErrorCode.errorCodeEmailAlreadyInUse != nil {
let emailExists = UIAlertController(title: "Oops!", message: "A user with this E-Mail already exists!", preferredStyle: UIAlertControllerStyle.alert)
emailExists.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
self.present(emailExists, animated: true, completion: nil)
}
else {
DispatchQueue.main.async () {
self.performSegue(withIdentifier: "signUpSucceededSegue", sender: self)
}
}
}
})
}
and
#IBAction func loginButton(_ sender: Any) {
FIRAuth.auth()?.signIn(withEmail: emailLoginField.text!, password: passwordLoginField.text!, completion: { (user: FIRUser?, error) in
if self.emailLoginField.text == "" || self.passwordLoginField.text == ""{
let alert = UIAlertController(title: "Alert", message: "E-Mail is Required", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
if FIRAuthErrorCode.errorCodeUserNotFound != nil {
let invalidLogin = UIAlertController(title: "Alert", message: "E-Mail/Password Incorrect", preferredStyle: UIAlertControllerStyle.alert)
invalidLogin.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
self.present(invalidLogin, animated: true, completion: nil)
}
else{
DispatchQueue.main.async () {
self.performSegue(withIdentifier: "loginSucceededSegue", sender: self)
}
}
}
})
are there any glaring logical errors at first glance or is there a better way to implement a segue into these functions?
Embed a Navigation Controller to the very first view of your storyboard
Then Try using this code:-
#IBAction func signUpComplete(_ sender: Any) {
if self.signUpEmailField.text == "" || self.signUpPasswordField.text == "" {
let alert = UIAlertController(title: "Oops!", message: "A valid E-mail and Password are Required", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}else{
FIRAuth.auth()?.createUser(withEmail: self.signUpEmailField!.text, password: self.signUpPasswordField!.text, completion: { (user, err) in
if let ErrorCode = FIRAuthErrorCode(rawValue: err!._code){
switch ErrorCode {
case .errorCodeEmailAlreadyInUse : let emailExists = UIAlertController(title: "Oops!", message: "A user with this E-Mail already exists!", preferredStyle: UIAlertControllerStyle.alert)
emailExists.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
self.present(emailExists, animated: true, completion: nil)
break
default : break
}
}else{
let nextView = self.navigationController!.storyboard!.instantiateViewController(withIdentifier: "signUpSucceededSegue")
self.navigationController!.pushViewController(nextView, animated: true)
}
})
}
}
Then alter your other code-block in the similar fashion.

How to disable a UIButton and send a UIAlertView message

I am trying to disable a menu button is the array is shows is empty.
This is my code.
#IBAction func likedmenubuttontouched(sender: AnyObject) {
if Globals.likedArray.isEmpty {
likedMenuButton.userInteractionEnabled = false
let ac = UIAlertController(title: "No liked quotes yet", message: "No liked quotes have been chosen, go explore!", preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
presentViewController(ac, animated: true, completion: nil)
return
} else {
likedMenuButton.userInteractionEnabled = true
}
}
And in ViewDidLoad()
likedMenuButton.userInteractionEnabled = false
I have managed to disable the button, but I want to send a message alerting the user why the button is disabled, otherwise, its a little confusing.
How would I go about doing this?
Thanks.
As by default the the user Interaction is true you need not to make it true
#IBAction func likedmenubuttontouched(sender: AnyObject) {
if Globals.likedArray.isEmpty {
let ac = UIAlertController(title: "No liked quotes yet", message: "No liked quotes have been chosen, go explore!", preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
presentViewController(ac, animated: true, completion: nil)
} else {
//segue to the other view
}
}
Also check your array count, that is why your wrong condition is executing

Resources