iOS Firebase: Retrieve and match database code to pass through authentication - swift

I'm trying to create an authentication security code for admin to login/ register. What I wish to do is login to perform segue if the user pass through the code which exists in firebase database. So now it doesn't works as Error alert box keep popping out event I have enter the correct security code.
let alertController = UIAlertController(title: "Security Code?", message: "Please enter your dedicated security code", preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "Next", style: .default) { (_) in
let code = alertController.textFields?[0].text
let scref=Database.database().reference();
scref.queryOrdered(byChild: "securitycode").queryEqual(toValue: code).observe(.value, with: { (snapshot) in
if (snapshot.exists())
{
Auth.auth().signIn(withEmail: self.emailText.text!, password: self.passwordText.text!, completion: { (user, error) in
if user != nil
{
//if sign in sucessful
self.performSegue(withIdentifier: "segueadmin", sender: self)
} else
{
if let myError = error?.localizedDescription{
print(myError)
let alertController = UIAlertController(title: "Error!", message: myError, preferredStyle: UIAlertControllerStyle.alert)
alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default) {
UIAlertAction in
// Insert code to run on button click below
self.printYes()
})
self.present(alertController, animated: true, completion: nil)
}else{
print("ERROR")
}
}
})}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in }
alertController.addTextField { (textField) in
textField.placeholder = "Enter Code:"
}
//adding the action to dialogbox
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
//finally presenting the dialog box
self.present(alertController, animated: true, completion: nil)
}
}

I think it might be an issue when you query your database.
Try this code :
scref.child("securitycode").child(code).observe(.value, with: { (snapshot) in
if (snapshot.exists()) {
...//Do your thing
}
With this your aim the reference /securitycode/{code} and if it exists it seems that there is a correct value stored in your database so you can proceed. If not the user can't proceed.

Oops! Very careless of me! It because of I didn't structure the data well and forgot to put " " for the data in Firebase.
So the firebase database should be:
And the code shall be:
ref=Database.database().reference().child("securitycode")
ref.queryOrdered(byChild: "code")
.queryEqual(toValue: self.textf.text)
.observe(DataEventType.value, with: { (snapshot) in

Related

How can I get Firebase Auth to display an error?

I want to set up email/password authentication with firebase, and have this written which is similar to the documentation. I have only one registered email that I'm testing with, and when I attempt to sign in with that everything works well. But when I enter another email/password, the completion block does not execute.
Auth.auth().signIn(withEmail: email, password: password) { [weak self] (user, error) in
guard let strongSelf = self else {
return
}
if let error = error {
let errorAlert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
errorAlert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
strongSelf.present(errorAlert, animated: true, completion: nil)
return
}
}
Nevermind I fixed it. I had a performSegue line right outside of the completion, when it should have been inside, after the guard and if let statement.

AWS Cognito getSession

I am trying log users as simply as possible using the signup and getSession function.
I have not encountered difficulties in using the signup function to create new users in my cognate user pool.
When I try to create a function for logging, I try this code :
func signin(){
let pool = AWSCognitoIdentityUserPool(forKey: AWSCognitoUserPoolSignInProviderKey)
let user = pool.getUser("toto")
user.getSession("toto", password: "BabaBobo1&", validationData: nil).continueWith(block: {[weak self] (task) -> Any? in
DispatchQueue.main.async {
if let error = task.error as? NSError {
let alertController = UIAlertController(title: error.userInfo["__type"] as? String,
message: error.userInfo["message"] as? String,
preferredStyle: .alert)
let retryAction = UIAlertAction(title: "Retry", style: .default, handler: nil)
alertController.addAction(retryAction)
self?.present(alertController, animated: true, completion: nil)
}else if let session = task.result {
let alertController = UIAlertController(title: "token",
message: session.accessToken?.tokenString,
preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(OKAction)
self?.present(alertController, animated: true, completion: nil)
}
}
return nil
})
}
It appears that the trailing block is never executed. Does anyone knows what I am doing wrong ?
My aim is to reduce the AWS linked code to the minimum. I want to avoid as much as possible to use the different delegate protocols provided in the SDK

AWS Cognito: Trying to Alert User of Error

I am having difficulty in capturing a Cognito Sign Up Error. I am trying to alert the user when Cognito returns a "UsernameExistsException","message":"User already exists" Error.
Below is my code:
self.pool!.signUp(usernameTextField.text!, password: passwordTextField.text!, userAttributes: attributes, validationData: nil).continue(successBlock: { (task:AWSTask!) in
// needs to be async so we can ALWAYS return nil for AWSTask
DispatchQueue.main.async {
if task.error != nil { // some sort of error
let myerror = task.error
print("\(myerror)")
let alert = UIAlertController(title: "Sign Up Error", message: (task.error?.localizedDescription)! as String, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
else {
let response: AWSCognitoIdentityUserPoolSignUpResponse = task.result! as AWSCognitoIdentityUserPoolSignUpResponse
// NSLog("AWSCognitoIdentityUserPoolSignUpResponse: \(response)")
self.user = response.user
let alert = UIAlertController(title: "Sign Up Successful", message: "", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: { action in self.performSegue(withIdentifier: "confrimationSegue", sender: self) }))
self.present(alert, animated: true, completion: nil)
}
}
return nil
})
For some reason am unable to break into the task.error != nil conditional statement. When I force an error the error does not print and alert action does not present to the view. Am I attempting to alert the user in the wrong function? How else can I check for the Username Already Exists error presented by cognito. Thanks in advance.
You are using a successBlock, which means that the block that you set is only going to be called when the sign up was performed succesfully. That's why the error is always nil.
In order to have the error, you should set the callback simply by something like the following:
userPool
.signUp(user.email, password: user.password, userAttributes: attributes, validationData: nil)
.continue({ response in
if let error = response.error {
// Error ocurred
} else {
// No error ocurred
})
This continue method only recieves the callback and will be called when a error happens.

Duplicate email Alert Swift + Parse

I'm trying to have it so when a user creates an account... if their email hasn't been used before an Alert box appears saying "Account created" and if the email is already in created (on Parse) then an alert should appear notifying the user.
I can't seem to get my code to do both..only display one message. What am I doing wrong here?
Thanks!
func createNewUser() {
let newUser = PFUser()
newUser.email = emailSignUp.text
newUser.username = emailSignUp.text
newUser.password = passwordSignUp.text
newUser.signUpInBackgroundWithBlock { ( success: Bool, error: NSError?) -> Void in
if newUser.username != nil {
let alert: UIAlertController = UIAlertController(title: "Account created", message: "Please confirm your email", preferredStyle: .Alert)
let okButton = UIAlertAction(title: "OK", style: .Default) { action -> Void in
}
alert.addAction(okButton)
self.presentViewController(alert, animated: true, completion: nil)
}
else {
let alert: UIAlertController = UIAlertController(title: "Email already registered", message: "Please enter a different email", preferredStyle: .Alert)
let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil)
alert.addAction(okButton)
self.presentViewController(alert, animated: true, completion: nil)
}
}
}
If memory serves the error that's returned if a user already exists is a different string than a generic error. You can try to match the error string and then display an alert if it matches or a different one if it's just an error (like the error string itself).
newUser.signUpInBackgroundWithBlock { ( success: Bool, error: NSError?) -> Void in
if error != nil {
if let errorString = error.userInfo?[“error”] as? String {
if errorString == “username \(emailSignUp.text) already taken” {
// Create alert that address is taken
} else {
// Create other case alert, though it may make sense to just display the error string in an alert box
}
}
} else {
// Do your usual stuff
}

Can't add an Alert Action to UIAlertController (Swift)

I'm trying to add an Ok button to a UI Alert but I cannot add it using alertController.addAction
What do I do in this case?
Thanks in advance!!
if error == nil {
let alert: UIAlertController = UIAlertController(title: "Account Created", message: "Please confirm your email", preferredStyle: .Alert)
let okButton = UIAlertAction(title: "Ok", style: .Default) { action -> Void in
self.performSegueWithIdentifier("toMain", sender: self)
alertController.addAction(okButton)
self.presentViewController(alert, animated: true, completion: nil)
}
} else {
println("\(error)")
}
alert instead of alertController
alert.addAction should be outside of your okbutton action.
Change your code with :
if error == nil {
let alert: UIAlertController = UIAlertController(title: "Account Created", message: "Please confirm your email", preferredStyle: .Alert)
let okButton = UIAlertAction(title: "Ok", style: .Default) { action -> Void in
self.performSegueWithIdentifier("toMain", sender: self)
}
alert.addAction(okButton)
self.presentViewController(alert, animated: true, completion: nil)
} else {
println("\(error)")
}