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.
FirebaseAuth
Firebase Storage
Firebase 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