AWS Cognito getSession - swift

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

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.

Unable to merge two firebase arrays in Firebase Database

Hello I am relatively new to Swift/Firebase and I am struggling to merge two arrays so that the downloadURL is seen amongst both the name and the email fields. One function adds the name and the email through the button click the other is another function to save the URL. When I try and merge them I get this (as seen in the image below). Here is my code:
#IBAction func createAccountAction(_ sender: AnyObject) {
let Users = Database.database().reference().child("Users")
let userDictionary : NSDictionary = ["email" : emailTextField.text as String!, "Name": nameTextField.text!]
Users.childByAutoId().setValue(userDictionary) {
(error, ref) in
if self.emailTextField.text == "" {
let alertController = UIAlertController(title: "Error", message: "Please enter your email and password", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
} else {
Auth.auth().createUser(withEmail: self.emailTextField.text!, password: self.passwordTextField.text!) { (user, error) in
if error == nil {
print("You have successfully signed up")
//Goes to the Setup page which lets the user take a photo for their profile picture and also chose a username
var imgData: NSData = NSData(data: UIImageJPEGRepresentation((self.profilePicture?.image)!, 0.8)!)
self.uploadProfileImageToFirebase(data: imgData)
let vc = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.present(vc, animated: true, completion: nil)
} else {
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
}
}
func addImageURLToDatabase(uid:String, values:[String:AnyObject]){
let Users = Database.database().reference().child("Users")
let ref = Database.database().reference(fromURL: "https://example.firebaseio.com/")
Users.updateChildValues(values) { (error, ref) in
if(error != nil){
print(error)
return
}
self.parent?.dismiss(animated: true, completion: nil)
}
}
Something like this is what you want. I removed a few variables from your function but you can add them back. I just wanted to make sure the code compiles.
#IBAction func createAccountAction(_ sender: AnyObject) {
let usersRef = Database.database().reference().child("Users")
let userDictionary : NSDictionary = ["email" : emailTextField.text!, "Name": nameTextField.text!]
if emailTextField.text == "" {
let alertController = UIAlertController(title: "Error", message: "Please enter your email and password", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
} else {
Auth.auth().createUser(withEmail: self.emailTextField.text ?? "", password: self.passwordTextField.text ?? "") { (result, error) in
if error != nil {
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
return
}
guard let user = result?.user else { return }
// HERE YOU SET THE VALUES
usersRef.child(user.uid).setValue(userDictionary, withCompletionBlock: { (error, ref) in
if error != nil { print(error); return }
self.addImageURLToDatabase(uid: user.uid, values: ["Put": "Your Values Here" as AnyObject])
})
}
}
}
func addImageURLToDatabase(uid:String, values:[String:AnyObject]){
let usersRef = Database.database().reference().child("Users").child(uid)
usersRef.updateChildValues(values) { (error, ref) in
if(error != nil){
print(error)
return
}
self.parent?.dismiss(animated: true, completion: nil)
}
}

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

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

CKSubscriptions and production container

Hi I'm trying to create a CKSubscription, I use this code:
func setupCKSubscriptions(){
if NSUserDefaults.standardUserDefaults().boolForKey("sub") == false{
let subscription = CKSubscription(recordType: "Quadri", predicate: NSPredicate(value: true), options: .FiresOnRecordCreation)
let notificationInfo = CKNotificationInfo()
notificationInfo.alertLocalizationKey = NSLocalizedString("NEW_Q", comment: "")
notificationInfo.shouldBadge = true
subscription.notificationInfo = notificationInfo
CKContainer.defaultContainer().publicCloudDatabase.saveSubscription(subscription) { (subscription, errore) -> Void in
if errore == nil{
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "sub")
NSUserDefaults.standardUserDefaults().synchronize()
let alert = UIAlertController(title: "Ok", message: "", preferredStyle: .Alert)
self.presentViewController(alert, animated: true, completion: nil)
}else{
print(errore?.localizedDescription)
let alert = UIAlertController(title: "Errore", message: errore?.localizedDescription, preferredStyle: .Alert)
self.presentViewController(alert, animated: true, completion: nil)
}
}
}else{
let alert = UIAlertController(title: "Errore", message: "", preferredStyle: .Alert)
self.presentViewController(alert, animated: true, completion: nil)
}
}
The problem is that this code only works on the simulator, when I run the app on a real device I get this error:
attempting to create a subscription in a production container.
How can I fix this?
I had exactly the same problem and the solution is easy, BUT NOT VERY INTUITIVE.
In development mode let the app create the subscription(s) you need. Deploy database to production.
Test your app in production and you'll see it can now create the subscription you have made.
Hope it works

Best way to combine mysql and Facebook sign up/in

There are two ways how to sign up to my iOS app. First option is using mysql/php (user types email,username,password and I store that in mysql database.
Second option is log in using Facebook and here starts my problem , because I need to have userId, which I can get from Facebook, but I also have an Id in my MySQL database(every user should have his own Id).
So my question is what would you recommend me to do. I have tried to store Facebook user to mysql so he received his unique Id.(but then there were empty columns like password, because Facebook user does not need password).
This is my Facebook sign in (when I sign in with my Facebook account it is ok because my Facebook id Is a pretty high number):
#IBAction func btnFBLoginPressed(sender: AnyObject) {
loadingIndicator.startAnimating()
FBSDKLoginManager().logInWithReadPermissions(["public_profile", "email"],
fromViewController:self,
handler: { (result:FBSDKLoginManagerLoginResult!, error:NSError!) -> Void in
if (error == nil){
self.getFBUserData()
self.loadingIndicator.stopAnimating()
}else{
self.loadingIndicator.stopAnimating()
let myAlert = UIAlertController(title: "Alert!", message: error.localizedDescription, preferredStyle: .Alert)
let okAction = UIAlertAction(title: "Ok", style: .Default, handler: nil)
myAlert.addAction(okAction)
self.presentViewController(myAlert, animated: true, completion: nil)
print(error.localizedDescription)
print("error")
return
}
})
}
func getFBUserData(){
if((FBSDKAccessToken.currentAccessToken()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil){
print(result)
print(result["name"])
print(result["id"])
NSUserDefaults.standardUserDefaults().setObject(result["name"]!, forKey: "username")
NSUserDefaults.standardUserDefaults().setObject(result["id"]!, forKey: "userId")
NSUserDefaults.standardUserDefaults().synchronize()
let firstPage = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController")as! ViewController
let appDelegate = UIApplication.sharedApplication().delegate
appDelegate?.window??.rootViewController = firstPage
}else{
let myAlert = UIAlertController(title: "Alert!", message: error?.localizedDescription, preferredStyle: .Alert)
let okAction = UIAlertAction(title: "Ok", style: .Default, handler: nil)
myAlert.addAction(okAction)
self.presentViewController(myAlert, animated: true, completion: nil)
print(error.localizedDescription)
print("error")
return
}
})
}
}
This is MySQL sign in:
#IBAction func loginTapped(sender: AnyObject) {
let userEmail = emailTextField.text
let userPassword = passwordTextField.text
if (userEmail!.isEmpty||userPassword!.isEmpty){
let myAlert = UIAlertController(title: "Alert", message: "All fields must be filled out", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "Ok", style: .Default, handler: nil)
myAlert.addAction(okAction)
self.presentViewController(myAlert, animated: true, completion: nil)
return
}
self.loadingIndicator.startAnimating()
let myUrl = NSURL(string: "http://localhost/~myPc/userSignIn.php")!
let request = NSMutableURLRequest(URL: myUrl)
request.HTTPMethod = "POST"
let postString = "userEmail=\(userEmail!)&userPassword=\(userPassword!)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) in
dispatch_async(dispatch_get_main_queue()){
if (error != nil){
let myAlert = UIAlertController(title: "Alert", message: error?.localizedDescription, preferredStyle: .Alert)
let okAction = UIAlertAction(title: "Ok", style: .Default, handler: nil)
myAlert.addAction(okAction)
self.presentViewController(myAlert, animated: true, completion: nil)
self.loadingIndicator.stopAnimating()
return
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if let parseJson = json {
let userId = parseJson["userId"] as? String
if userId != nil{
NSUserDefaults.standardUserDefaults().setObject(parseJson["username"], forKey: "username")
NSUserDefaults.standardUserDefaults().setObject(parseJson["userId"], forKey: "userId")
NSUserDefaults.standardUserDefaults().synchronize()
let firstPage = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController")as! ViewController
let appDelegate = UIApplication.sharedApplication().delegate
appDelegate?.window??.rootViewController = firstPage
}else{
let userMessage = parseJson["message"] as? String
let myAlert = UIAlertController(title: "Alert", message: userMessage, preferredStyle: .Alert)
let okAction = UIAlertAction(title: "Ok", style: .Default, handler: nil)
myAlert.addAction(okAction)
self.presentViewController(myAlert, animated: true, completion: nil)
self.loadingIndicator.stopAnimating()
}
self.loadingIndicator.stopAnimating()
}
} catch {
print(error)
}
}
}).resume()
}