I am creating a LINE clone application for learning Firebase and chat function, and I will post the implementation of membership registration using Firebase as a memorandum. I am a beginner, so if you have any corrections, please point them out.
This time, in implementing the membership registration function, the order is as follows.
FirebaseAuthFirebase StorageFirebase Firestore--Registration is possible (new registration button is valid) if all of email address, password, and username are filled in.
--1. When processing , after completing the membership registration using the approval email2. It seems that it is a common method to move to the processing of, but since the purpose of this time was for learning, that area is not considered.
【Xcode】Version 12.0.1 【Swift】Version 5.3 【CocoaPods】version 1.9.3 【Firebase】version 6.29.0

SignUpModel.swift
import Foundation
import Firebase
//delegate wants to weak reference, so inherit class
protocol SignUpModelDelegate: class {
func createImageToFirestorageAction()
func createUserToFirestoreAction(fileName: String?)
func completedRegisterUserInfoAction()
}
class SignUpModel {
//delegate references weak to avoid memory leak
weak var delegate: SignUpModelDelegate?
func createUser(email: String, password: String) {
//Save to Firebase Auth
Auth.auth().createUser(withEmail: email, password: password) { (res, err) in
if let err = err {
print("Failed to save to Firebase Auth.\(err)")
//Processing when registration of user information fails
return
}
print("Successfully saved to Firebase Auth.")
//Completed saving to Firebase Auth->Save to Firebase Storage
self.delegate?.createImageToFirestorageAction()
}
}
func creatrImage(fileName: String, uploadImage: Data) {
//Save to Firebase Storage
let storageRef = Storage.storage().reference().child("profile_image").child(fileName)
storageRef.putData(uploadImage, metadata: nil) { (metadate, err) in
if let err = err {
print("Failed to save to Firestorage.\(err)")
//Processing when registration of user information fails
return
}
print("Successfully saved to Firestorage.")
//Completed saving to Firebase Storage->Save to Firebase Firestore
self.delegate?.createUserToFirestoreAction(fileName: fileName)
}
}
func createUserInfo(uid: String, docDate: [String : Any]) {
//Save to Firebase Firestore
Firestore.firestore().collection("users").document(uid).setData(docDate as [String : Any]) { (err) in
if let err = err {
print("Failed to save to Firestore.\(err)")
//Processing when registration of user information fails
return
}
print("You have successfully saved to the Firestore.")
//Processing when registration of user information is completed
self.delegate?.completedRegisterUserInfoAction()
}
}
}
SignUpViewController.swift
import UIKit
import Firebase
import FirebaseStorage
import IQKeyboardManagerSwift
class SignUpViewController: UIViewController {
@IBOutlet weak var profileImageButton: UIButton!
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var userNameTextField: UITextField!
@IBOutlet weak var signUpButton: UIButton!
let signUpModel = SignUpModel()
override func viewDidLoad() {
super.viewDidLoad()
IQKeyboardManager.shared.enable = true
emailTextField.delegate = self
passwordTextField.delegate = self
userNameTextField.delegate = self
signUpModel.delegate = self
//Processing about screen UI
setupUI()
}
//Processing about screen UI
func setupUI() {
signUpButton.layer.cornerRadius = 3
signUpButton.isEnabled = false
profileImageButton.layer.masksToBounds = true
profileImageButton.layer.cornerRadius = 75
profileImageButton.layer.borderColor = UIColor.lightGray.cgColor
profileImageButton.layer.borderWidth = 0.1
}
//Select profile image (transition to photo library)
@IBAction func profileImageButtonAction(_ sender: Any) {
let imagePickerController = UIImagePickerController()
imagePickerController.allowsEditing = true
imagePickerController.delegate = self
self.present(imagePickerController, animated: true, completion: nil)
}
//New registration process
@IBAction func signUpButtonAction(_ sender: Any) {
guard let email = emailTextField.text,
let password = passwordTextField.text
else { return }
//Save to Firebase Auth
signUpModel.createUser(email: email, password: password)
}
#···abridgement···
//Processing to save profile image to Firebase Storage
private func createImageToFirestorage() {
//Processing when profile image is set
if let image = self.profileImageButton.imageView?.image {
let uploadImage = image.jpegData(compressionQuality: 0.5)
let fileName = NSUUID().uuidString
//Save to Firebase Storage
signUpModel.creatrImage(fileName: fileName, uploadImage: uploadImage!)
} else {
print("Since the profile image is not set, it will be the default image.")
//Save User information to Firebase Firestore
self.createUserToFirestore(profileImageName: nil)
}
}
//Process to save User information in Firebase Firestore
private func createUserToFirestore(profileImageName: String?) {
guard let email = Auth.auth().currentUser?.email,
let uid = Auth.auth().currentUser?.uid,
let userName = self.userNameTextField.text
else { return }
//Define saved contents (dictionary type)
let docData = ["email": email,
"userName": userName,
"profileImageName": profileImageName,
"createdAt": Timestamp()] as [String : Any?]
//Save to Firebase Firestore
signUpModel.createUserInfo(uid: uid, docDate: docData as [String : Any])
}
}
extension SignUpViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
//Method called when a photo is selected
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let editedImage = info[.editedImage] as? UIImage {
profileImageButton.setImage(editedImage.withRenderingMode(.alwaysOriginal), for: .normal)
} else if let originalImage = info[.originalImage] as? UIImage {
profileImageButton.setImage(originalImage.withRenderingMode(.alwaysOriginal), for: .normal)
}
dismiss(animated: true, completion: nil)
}
}
extension SignUpViewController: UITextFieldDelegate {
//Method called when the text selection is changed in textField
func textFieldDidChangeSelection(_ textField: UITextField) {
//Variable to determine if textField is empty(Bool type)Defined in
let emailIsEmpty = emailTextField.text?.isEmpty ?? true
let passwordIsEmpty = passwordTextField.text?.isEmpty ?? true
let userNameIsEmpty = userNameTextField.text?.isEmpty ?? true
//Processing when all textFields have been filled in
if emailIsEmpty || passwordIsEmpty || userNameIsEmpty {
signUpButton.isEnabled = false
signUpButton.backgroundColor = UIColor.systemGray2
} else {
signUpButton.isEnabled = true
signUpButton.backgroundColor = UIColor(named: "lineGreen")
}
}
//Keyboard closes when you press anything other than textField
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
}
extension SignUpViewController: SignUpModelDelegate {
//Completed saving to Firebase Auth->Save to Firebase Storage
func createImageToFirestorageAction() {
print("Successfully saved to Firebase Auth.")
self.createImageToFirestorage()
}
//Completed saving to Firebase Storage->Save to Firebase Firestore
func createUserToFirestoreAction(fileName: String?) {
print("Successfully saved to Firestorage.")
self.createUserToFirestore(profileImageName: fileName)
}
//Processing when registration of user information is completed
func completedRegisterUserInfoAction() {
//Screen transition to ChatListViewController
let storyboard = UIStoryboard(name: "ChatList", bundle: nil)
let chatListVC = storyboard.instantiateViewController(withIdentifier: "ChatListVC") as! ChatListViewController
let nav = UINavigationController(rootViewController: chatListVC)
nav.modalPresentationStyle = .fullScreen
nav.modalTransitionStyle = .crossDissolve
self.present(nav, animated: true, completion: nil)
}
}
Since we are focusing on the processing related to Firebase, we will omit the explanation of the following items.
--About error handling
--About ʻUIActivityIndicatorView --About ʻUIImagePickerController
--About ʻIQKeyboardManagerSwift` (For details, please refer to here.)
We will proceed on the premise that the following items have been completed.
--Creating a Firebase project --Built-in Firebase SDK in Xcode
If you haven't heard about this yet, please refer to Documentation.
Add the following to the Podfile and do pod install in the terminal.
pod 'Firebase/Analytics'
pod 'Firebase/Auth'
pod 'Firebase/Core'
pod 'Firebase/Firestore'
pod 'Firebase/Storage'
pod 'FirebaseUI/Storage'
Select Mail / Password from the Sign-in method tab as shown above. Open the edit screen with the pencil icon.
Save it once enabled. This is the end of the preparation.
SignUpViewController.swift
//New registration process
@IBAction func signUpButtonAction(_ sender: Any) {
guard let email = emailTextField.text,
let password = passwordTextField.text
else { return }
//Save to Firebase Auth
signUpModel.createUser(email: email, password: password)
}
SignUpModel.swift
func createUser(email: String, password: String) {
//Save to Firebase Auth
Auth.auth().createUser(withEmail: email, password: password) { (res, err) in
if let err = err {
print("Failed to save to Firebase Auth.\(err)")
//Processing when registration of user information fails
return
}
print("Successfully saved to Firebase Auth.")
//Completed saving to Firebase Auth->Save to Firebase Storage
self.delegate?.createImageToFirestorageAction()
}
}
SignUpViewController.swift
//Completed saving to Firebase Auth->Save to Firebase Storage
func createImageToFirestorageAction() {
print("Successfully saved to Firebase Auth.")
self.createImageToFirestorage()
}
SignUpViewController.swift
//Processing to save profile image to Firebase Storage
private func createImageToFirestorage() {
//Processing when profile image is set
if let image = self.profileImageButton.imageView?.image {
//Compress image
let uploadImage = image.jpegData(compressionQuality: 0.5)
//Get a unique ID
let fileName = NSUUID().uuidString
//Save to Firebase Storage
signUpModel.creatrImage(fileName: fileName, uploadImage: uploadImage!)
} else {
print("Since the profile image is not set, it will be the default image.")
//Save User information to Firebase Firestore
self.createUserToFirestore(profileImageName: nil)
}
}
SignUpModel.swift
func creatrImage(fileName: String, uploadImage: Data) {
//Save to Firebase Storage
let storageRef = Storage.storage().reference().child("profile_image").child(fileName)
storageRef.putData(uploadImage, metadata: nil) { (metadate, err) in
if let err = err {
print("Failed to save to Firestorage.\(err)")
//Processing when registration of user information fails
return
}
print("Successfully saved to Firestorage.")
//Completed saving to Firebase Storage->Save to Firebase Firestore
self.delegate?.createUserToFirestoreAction(fileName: fileName)
}
}
SignUpViewController.swift
//Completed saving to Firebase Storage->Save to Firebase Firestore
func createUserToFirestoreAction(fileName: String?) {
print("Successfully saved to Firestorage.")
self.createUserToFirestore(profileImageName: fileName)
}
SignUpViewController.swift
//Process to save User information in Firebase Firestore
private func createUserToFirestore(profileImageName: String?) {
guard let email = Auth.auth().currentUser?.email,
let uid = Auth.auth().currentUser?.uid,
let userName = self.userNameTextField.text
else { return }
//Define saved contents (dictionary type)
let docData = ["email": email,
"userName": userName,
"profileImageName": profileImageName,
"createdAt": Timestamp()] as [String : Any?]
//Save to Firebase Firestore
signUpModel.createUserInfo(uid: uid, docDate: docData as [String : Any])
}
SignUpModel.swift
func createUserInfo(uid: String, docDate: [String : Any]) {
//Save to Firebase Firestore
Firestore.firestore().collection("users").document(uid).setData(docDate as [String : Any]) { (err) in
if let err = err {
print("Failed to save to Firestore.\(err)")
//Processing when registration of user information fails
return
}
print("You have successfully saved to the Firestore.")
//Processing when registration of user information is completed
self.delegate?.completedRegisterUserInfoAction()
}
}
SignUpViewController.swift
//Processing when registration of user information is completed
func completedRegisterUserInfoAction() {
//Screen transition to ChatListViewController
#···abridgement···
}
-[Swift] LINE-style Chat app creation (Ep1) --Explanation of overview and creation of ChatList screen -[Firebase] [iOS] Let's create a membership function with Firebase Authentication -[IOS] How to save / retrieve images to Firebase Storage
Recommended Posts