[SwiftUI Firebase] Email Login

Woozoo·2023년 4월 4일

[SwiftUI Firebase]

목록 보기
1/14

초기 세팅

import SwiftUI
import Firebase

@main
struct SwiftfulFirebaseApp: App {
    
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()
        print("Firebase Configured")
        return true
    }
}

Firebase초기 설정!
init구문에서 FirebaseApp.configure를 해줘도 되고
지금처럼 AppDelegate 만들고 추가해줘도 됨


이메일로 로그인 하기1

로그인은 FirebaseAuth 패키지가 설치되야한다

tutorial엔 Firebase Core를 임포트 해주라고 나오는데
import Firebase 로 충분함



AuthenticationView 라는 간단한 뷰를 구성해줌


위에 버튼 누르면 네비게이션 되는 Email이랑 비밀번호 입력하는 뷰도 뷰모델도 구성해줌
(비밀번호는 SecureField로 만들 수 있구나!)


Auth에 관한 매니저를 만들어서 뷰와 뷰모델과는 별개로 사용할 수 있게 해주자! 이러면 다른 앱에서도 사용해볼 수 있겠죠

import Foundation
import FirebaseAuth

final class AuthenticationManager {
    static let shared = AuthenticationManager()
    private init() { }
    
    func createUser(email: String, password: String) async throws {
        let authDataResult = try await Auth.auth().createUser(withEmail: email, password: password)
    }
}

createUser를 하는
authDataResult의 타입은 AuthDataResult타입인데 Firebase에서 만들어진 타입임!
이걸 사용하는 것보다 우리가 모델 만들어서 넣어주는 게 좋을 것 같습니다

import Foundation
import FirebaseAuth

struct AuthDataResultModel {
    let uid: String
    let email: String?
    let photoUrl: String?
    
    init(user: User) {
        self.uid = user.uid
        self.email = user.email
        self.photoUrl = user.photoURL?.absoluteString
    }
}

final class AuthenticationManager {
    static let shared = AuthenticationManager()
    private init() { }    
    
    func createUser(email: String, password: String) async throws -> AuthDataResultModel {
        let authDataResult = try await Auth.auth().createUser(withEmail: email, password: password)
        return AuthDataResultModel(user: authDataResult.user)
    }
}

AuthDataResultModel을 만들어주고 init될 때 User를 받아서 넘겨주는 model을 구성, createUser의 반환 값으로 AuthDataResultModel이 반환되게 해줌


SignInEmailViewModel로 돌아와서

@MainActor
final class SignInEmailViewModel: ObservableObject {
    @Published var email = ""
    @Published var password = ""
    
    func signIn() {
        guard !email.isEmpty, !password.isEmpty else {
            print("No email or password found")
            return
        }
        
        Task {
            do {
                let returnedUserData = try await AuthenticationManager.shared.createUser(email: email, password: password)
                print("Success")
                print(returnedUserData)
            } catch {
                print("error: \(error)")
            }
        }
    }
}

signIn 메소드를 작성해줬다!
가드문으로 필드가 비었을 때 막아주고
Task로 do catch 구문에서 Success 와 Error일 때 작성해줌


그리고 버튼 누를 때 SignIn되게 해주면

User가 생성되었습니다~!


RootView를 만들어줌


getAuthenticatedUser 메소드를 만들어줬는데
Auth.auth().currentUser 메소드로 로그인한 정보가 가져와지나봄


signOut도 가능하게 해줌

  • AuthenticationManager의 getAuthenticatedUser()메소드가 로그인 된 정보를 가져와준다고 생각하면 된다!

AuthenticationManager에서 User타입을 인지 못해서 import Firebase도 해줬음!


Sign In with Email & Password 2

RootView에서 showSignInView 불 값에 따라서
AuthenticationView를 띄워주개 되는데
SettingsView에도 이 Bool값이 바인딩 되어 있고(로그아웃 했을 때)
AuthenticationView의 하위 SignInEmailView에도 이 값이 바인딩 되어 있다!
로그인 하면 false로 바뀌고 RootView가 떠야하니까!

그리고 지금 당장은 signIn메소드 내에서 사용하는 returnedUserData를 어딘가에서 사용하고 있지않음! 이럴 때 @discardableResult를 붙여주면 됩니다
(그리고 let returnedUserData는 지워줘도됨)


viewModel의 signIn메소드는 요렇게 Task안에서 do catch로 처리가 되고 !

지금 SignIn을 하게 될 땐 createUser만 해주고 있어서
이미 있는 유저 계정으로 로그인할 땐 로그인이 안되고 있음


AuthManager에서 SignInUser 메소드를 만들어주고!


기존에 있던 메소드는 signUp으로 네이밍 해주고
아래에 새로운 signIn메소드를 구성해줬음


그리고 버튼내에서 signUp이 성공했을 때 Return 으로 빠져나오게 해줘서 signUp을 성공하면 아래의 signIn메소드가 실행되지 않게 해줬다!


password Reset도 구현해봅시다


AuthenticationManager에서 메소드를 구현해줬다

authUser를 가져와서 authUser의 email을 가지고 resetPassword가 가능해지게 해줌


보내는 메일의 형식은 여기서 바꿔줄 수 있음!

자세히 알아보기 클릭해서 들어가면 어떻게 바꿀지 보임
(사실은 Settings page가서 바꿔줘야됩니다~)


AuthenticationManager에서 update하는 메소드도 구현해줌

SettingsViewModel에서 방금 작성한애들이 들어간 메소드 작성해주고!

이제 업데이트도 가능해졌습니다~!
(업데이트 할려면 다시 로그인 해줘야지 가능함)

profile
우주형

0개의 댓글