Copy the showError function that is in the SignUpViewController and paste that in the current View Controller.
Oh ok. So all 3 are meant to LoginViewController? I have put it in a NicknameViewController, thinking that the user could set it up there. I miss understood. Also I am assuming that I need to add and extra field for the Nickname to be entered along side the email and password, correct? I just added the code to LoginViewController, but still has that error:
import UIKit
import FirebaseAuth
import FirebaseCore
import AVFoundation
import FirebaseFirestore
class LoginViewController: UIViewController {
@IBOutlet var emailTextField: UITextField!
@IBOutlet var passwordTextField: UITextField!
@IBOutlet var loginButton: UIButton!
@IBOutlet var errorLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
setUpElements()
}
func setUpElements() {
// Hide error label
errorLabel.alpha = 0
// Style the elements
Utilities.styleTextField(emailTextField)
Utilities.styleTextField(passwordTextField)
Utilities.styleFilledButton(loginButton)
}
// 7. There's something wrong with the fields, show error message
func showError(message:String) {
errorLabel.text = message
errorLabel.alpha = 1
}
@IBAction func loginTapped(_ sender: Any) {
// 1. Validate Textfields
// 3. Create Cleaned verson of the Textfield
let email = emailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let password = passwordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
// 2. Signing in user
Auth.auth().signIn(withEmail: email, password: password) { (result, error) in
if error != nil {
// 4. Couldn't sign in
self.errorLabel.text = error!.localizedDescription
self.errorLabel.alpha = 1
}
else {
loginUser { success in
if success {
self.getProfileImage { returnedImage in
if let image = returnedImage {
self.logoImageView.image = image
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.transitionToHome()
}
}
}
if let nickname = self.nicknameTextField.text, self.nicknameTextField.text != "" {
self.addNickname(nickname: nickname)
}
}
}
// 5. Transition to homescreen
let profileVC = UIStoryboard(name: "Main", bundle: nil)
let controller = profileVC.instantiateViewController(identifier: "tasks") as! TasksViewController
controller.modalPresentationStyle = .fullScreen
//present(controller , animated: true)
self.view.window?.rootViewController = UINavigationController(rootViewController: controller)
self.view.window?.makeKeyAndVisible()
}
}
}
func addNickname(nickname: String) {
let cleanedNickname = nickname.trimmingCharacters(in: .whitespacesAndNewlines)
// Check if nickname is unique
isNicknameUnique(nickname: cleanedNickname) { isUnique in
if isUnique {
let db = Firestore.firestore()
// Where users document ID is set to currentUser.uid
// let user = db.collection("users").document("\(Auth.auth().currentUser?.uid ?? ""))")
// user.setData(["nickname": cleanedNickname], merge: true)
// OR
// Where users document ID is automatically created.
let users = db.collection("users")
let query = users.whereField("uid", in: [Auth.auth().currentUser?.uid ?? ""])
query.getDocuments { snapshot, error in
if let error = error {
self.showError(message: error.localizedDescription)
} else if let snapshot = snapshot {
for doc in snapshot.documents {
let user = db.collection("users").document("\(doc.documentID)")
user.setData(["nickname": cleanedNickname], merge: true)
self.showError(message: "Nickname saved.")
}
}
}
} else {
self.showError(message: "Nickname is already in use.")
}
}
}
func isNicknameUnique(nickname: String, completion: @escaping (Bool) -> Void) {
let db = Firestore.firestore()
// Set flag to true initially
var isUnique = true
let currentUserId = Auth.auth().currentUser?.uid ?? ""
let users = db.collection("users")
users.getDocuments { snapshot, error in
guard error == nil else {
self.showError(message: "Error retrieving records. Try again later.")
return
}
if let snapshot = snapshot {
for doc in snapshot.documents {
if let thisNickname = doc["nickname"] as? String, currentUserId != doc["uid"] as? String {
if thisNickname == nickname {
// Set flag to false
isUnique = false
break
}
}
}
}
completion(isUnique)
}
}
}
In my case I put the code in the LoginViewController just for the purposes of testing that the code works.
If you had intended to have a NicknameViewController then that’s fine. Do all the nickname stuff in there and leave the LoginViewController just for the purposes of enabling the user to log in.
Perfect. Also… It seem as though the code wants to display the user’s profile pic …the part where getProfileImage is located. Correct? And, The only error left is: Cannot find ‘loginUser’ in scope. What am I missing?