Show Login/Signup Errors with firebase - swift

I want to show the error to the user while logging in if the information is incorrect. Such as invalid username/Password etc
#IBAction func signIn(_ sender: Any) {
Auth.auth().signIn(withEmail: emailTextField.text!, password: passwordTextField.text!) { (user, error) in
if error != nil {
//self.createAlert(titleText: "Error", messageText: String(describing: error?.localizedDescription))
return
} else {
self.performSegue(withIdentifier: "signInToTabBarVC", sender: nil)
print("Signed In")
}
}
}
I also want to show sign up errors. Including email is already in use or username or password is too weak
Auth.auth().createUser(withEmail: emailField.text! , password: passwordField.text!, completion: { (user: User?, error: Error?) in
if error != nil {
print(error!.localizedDescription)
return
}
let uid = user?.uid
let storageRef = Storage.storage().reference(forURL: "gs://vloggle-cb375.appspot.com").child("profile_picture").child(uid!)
if let chosenImg = self.chosenImage, let imageData = UIImageJPEGRepresentation(chosenImg, 0.1) {
storageRef.putData(imageData, metadata: nil, completion: { (metadata, error) in
if error != nil {
return
}
let profileImageUrl = metadata?.downloadURL()?.absoluteString
self.setUserInformation(profileImageUrl: profileImageUrl!, username: self.usernameField.text!, email: self.emailField.text!, uid: uid!)
})
}
})
}

you can show error message with the help of UIAlertView
let dialog = UIAlertController(title: error!.localizedDescription, message: "", preferredStyle: UIAlertControllerStyle.alert)
dialog.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
DispatchQueue.main.async(execute: {
self.present(dialog, animated: true, completion: nil)
})

Related

validate always return true even though email format is incorrect

func createUser(_ email: String, _ password: String) -> Bool
{
var validate = true
Auth.auth().createUser(withEmail: email, password: password)
{
(authResult, error) in
if error != nil
{
validate = false
}
}
return validate
}
//validate email and register using registercontroller
let canRegister = RC.createUser(email!, password!)
var message = ""
if canRegister
{
message = "Welcome \(name)"
let alert = UIAlertController(title: "Register Success", message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Back", style: .default, handler:
{ Void in
self.dismiss(animated: true, completion: nil)
}))
self.present(alert,animated:true, completion:nil)
print(String(canRegister))
return
}
else
{
lblErrorText.text = "Invalid email format or email already existed"
print(String(canRegister))
return
}
I'm doing a simple firebase register process, however even though the email format is incorrect, validate will always return as true
though it will not register into firebase. I want it to return false if error exists.
Create user is an asynchnous method
func createUser(_ email: String, _ password: String,completion:#escaping(Bool -> ())) {
Auth.auth().createUser(withEmail: email, password: password)
{
(authResult, error) in
completion(error == nil)
}
}
then
RC.createUser(email!, password!) { canRegister in
if canRegister
{
message = "Welcome \(name)"
let alert = UIAlertController(title: "Register Success", message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Back", style: .default, handler:
{ Void in
self.dismiss(animated: true, completion: nil)
}))
self.present(alert,animated:true, completion:nil)
print(String(canRegister))
return
}
else
{
lblErrorText.text = "Invalid email format or email already existed"
print(String(canRegister))
return
}
}

How to add another key/value to Firebase Array

The problem that I'm facing is that I have successfully created the array and have displayed the values like so:
Users
-uid
- Name: Example
- Profile Pic URL: example12345
- email: example#example.co.uk
However, in another swift file I have successfully generated a personality type and am struggling to add this to the array so that I end up with something that looks like this:
Users
-uid
- Name: Example
- Profile Pic URL:
- email: example#example.co.uk
- personality type: INTJ
I have tried copying the code from the previous swift class to no avail
This is the code for the working firebase array
#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 }
let vc = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.present(vc, animated: true, completion: nil)
// HERE YOU SET THE VALUES
usersRef.child(user.uid).setValue(userDictionary, withCompletionBlock: { (error, ref) in
if error != nil { print(error); return }
let imageName = NSUUID().uuidString
let storageRef = Storage.storage().reference().child("profile_images").child("\(imageName).png")
if let profileImageUrl = self.profilePicture.image, let uploadData = UIImageJPEGRepresentation(self.profilePicture.image!, 0.1) {
storageRef.putData(uploadData, metadata: nil, completion: { (metadata, error) in
if error != nil, metadata != nil {
print(error ?? "")
return
}
storageRef.downloadURL(completion: { (url, error) in
if error != nil {
print(error!.localizedDescription)
return
}
if let profileImageUrl = url?.absoluteString {
self.addImageURLToDatabase(uid: user.uid, values: ["profile photo URL": profileImageUrl as AnyObject])
}
})
})
}
}
)}
}
}
This is the other swift file function which generates the personality type which I would like to add to the array
#IBAction func JPbtn(_ sender: Any) {
if (Judging < Perceiving){
Result3 = "P"
} else {
Result3 = "J"
}
let PersonalityType = "\(Result) \(Result1) \(Result2) \(Result3)"
print(PersonalityType)
let vc = self.storyboard?.instantiateViewController(withIdentifier: "Example") as! ViewController
self.present(vc, animated: true, completion: nil)
}
So if you are just trying to add a new key with a value, all you need to do is create a new reference like this.
guard let currentUserUID = Auth.auth().currentUser?.uid else { return }
print(currentUserUID)
let userPersonalityRef = Database.database().reference().child("users").child(currentUserUID).child("personality")
userPersonalityRef.setValue("Some Value")
When you set the value it can also be a dictionary if you want. But if your users don't all have personality make sure it optional on your data model or else It might crash your app. When you are getting your user from firebase.

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)
}
}

Swift and Firebase Database - Missing argument label 'andPriority' in call

The code below is being used to update my firebase database when a user registers in the app, it is suppose to authenticate the user in the database and also save a boolean value. I get the following error when this is implemented (see below).
#IBAction func signupPressed(_ sender: UIButton) {
Auth.auth().createUser(withEmail: emailEntryField.text!, password: passwordEntryField.text!) { (user, error) in
if error == nil {
//Show SVProgressHUD
SVProgressHUD.show()
//save User to Database
let newUserInfo : [String:Any] = ["email":self.emailEntryField.text!, "state":true]
self.ref.child("users").child(user?.user.uid).setValue(newUserInfo, withCompletionBlock: { (error, ref) in
print("New User Saved")
}
//Dismiss SVProgressHUD
SVProgressHUD.dismiss()
//move to info view controller
self.performSegue(withIdentifier: "signupToInfo", sender: self)
} else {
print("Signup Unsuccessul")
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)
}
}
}
There is a missing ) after the block
self.ref.child("users").child(user?.user.uid).setValue(newUserInfo, withCompletionBlock: { (error, ref) in
print("New User Saved")
}
Add ) at the end, like this
self.ref.child("users").child(user?.user.uid).setValue: newUserInfo, withCompletionBlock: { (error, ref) in
print("New User Saved")
})
Hope it helps

navigation controller doesn't work

Signup UIViewController design that validates email, password and confirm password.
Signup is embedded in NavigationController
func showAlert(ttl:String,msg:String){
let alert = UIAlertController(title: "\(ttl)", message: "\(msg)", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
#IBAction func signUp(_ sender: UIButton) {
if (email.text != nil && password.text != nil && confrimPassword.text != nil){
if !(isValidEmail(testStr: email.text!)){
showAlert(ttl: "Invaild Email-ID", msg: "Please enter an valid Email-ID")
}
else if !(isValidPassword(testStr: password.text)){
showAlert(ttl: "Invalid Password", msg: "Password must have at least one uppercase,one digit,one lowercase and minimum 8 characters")
}
else if !(passwordMatch(password: password.text!, confirmPassword: confrimPassword.text!)){
showAlert(ttl: "Passwords doesn't Match", msg: "Please re-enter your password")
}
else{
if Connectivity.isConnectedToInternet {
Authentication.Signup(for: email.text!, password: password.text!,finished: { resdata in do{ let res = try JSONSerialization.jsonObject(with: resdata) as! Dictionary<String, AnyObject>
print(res)
DispatchQueue.main.async {
let view: Verification = self.storyboard?.instantiateViewController(withIdentifier: "Verify") as! Verification
view.email = self.email.text!
//doesnot work
self.navigationController?.pushViewController(view, animated: true)
}
}
catch{
print("Error")
}
})
}
else{
showAlert(ttl: "No Internet", msg: "Please check your internet connection")
}
}
}
else{
self.showAlert(ttl: "Enter all Credentials", msg: " ")
}
}
}
Tried using segue also that doesn't suit my requirements
#IBAction func signUp(_ sender: UIButton) {
Authentication.Signup(for: email.text!, password: password.text!,finished: { resdata in do{
let res = try JSONSerialization.jsonObject(with: resdata) as! Dictionary<String, AnyObject>
print(res)
DispatchQueue.main.async {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "Verify") as! Verification
controller.email = self.email.text!
self.present(controller, animated: true, completion: nil)
}
}