[UIKit] Firebase Chat App: Google Sign In & Sign Out

Junyoung Park·2022년 9월 17일
0

UIKit

목록 보기
34/142
post-thumbnail

Swift: Firebase Chat App Part 7 - Google Sign In & Sign Out (Real-time) - Xcode 11 - 2020

Firebase Chat App: Google Sign In & Sign Out

구현 목표

  • 구글 간편 로그인
  • 노티피케이션 옵저버 등록 → 노티를 통해 동작 구현

구현 태스크

  1. 구글 로그인 디펜던시 등록
  2. 구글 로그인 버튼 UI 및 로그인 함수 구현
  3. 파이어베이스 실시간 데이터베이스 데이터 등록
  4. 노티피케이션 등록 → 로그인 이후 자동으로 네비게이션 이동

핵심 코드

    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        ApplicationDelegate.shared.application(app, open: url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
            annotation: options[UIApplication.OpenURLOptionsKey.annotation]
        )
        return GIDSignIn.sharedInstance.handle(url)
    }
  • AppDelegate 내 url에 따라 값을 리턴하는 함수
  • 페이스북 및 구글 로그인 관련 메소드 등록
    private let googleLoginButton: GIDSignInButton = {
        let button = GIDSignInButton()
        return button
    }()
    @objc private func googleSignIn() {
        guard let clientID = FirebaseApp.app()?.options.clientID else { return }
        let config = GIDConfiguration(clientID: clientID)
        GIDSignIn.sharedInstance.signIn(with: config, presenting: self) { [unowned self] user, error in
            if let error = error {
                print(error.localizedDescription)
                return
            }
            guard
                let authentication = user?.authentication,
                let idToken = authentication.idToken else { return }
            
            guard
                let email = user?.profile?.email,
                let firstName = user?.profile?.givenName,
                let lastName = user?.profile?.familyName else { return }
            
            DatabaseManager.shared.userExists(with: email, at: Platform.Google) { exists in
                if !exists {
                    DatabaseManager.shared.insertUser(with: ChatAppUser(firstName: firstName, lastName: lastName, emailAddress: email, platform: .Google))
                }
            }
            
            let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: authentication.accessToken)
            
            FirebaseAuth.Auth.auth().signIn(with: credential) { [weak self] result, error in
                guard let self = self else { return }
                guard
                    result != nil,
                    error == nil else {
                    if let error = error {
                        print("Facebook credential login failed, MFA may be needed - \(error)")
                    }
                    return
                }
                print("Successfully logged user in")
                NotificationCenter.default.post(name: .didSignInNotification, object: nil)
            }
        }
    }
  • 구글 로그인 버튼 UI 및 관련 함수 추가
  • GIDSignIn.sharedInstancesignIn 메소드를 통해 클라이언트 아이디 전달 및 인증 가능
  • 유저 데이터(이메일, 이름 등) 패치 가능
  • 페이스북 인증과 동일한 방법으로 파이어베이스 인증 FirebaseAuth.Auth.auth().signIn(with: AuthCredentail)로 로그인
	private var signInObserver: NSObjectProtocol?

    private func setObserver() {
        signInObserver = NotificationCenter.default.addObserver(forName: Notification.Name.didSignInNotification, object: nil, queue: .main, using: { [weak self] _ in
            guard let self = self else { return }
            self.navigationController?.dismiss(animated: true, completion: nil)
        })
    }
    
    deinit {
        if let observer = signInObserver {
            NotificationCenter.default.removeObserver(observer)
            print("Observer removed")
        }
    }
  • 커스텀 노티피케이션 구현
  • 로그인 시 해당 노티를 주고 노티를 받으면 현재 네비게이션 컨트롤러의 스택을 디스미스(즉 메인 뷰로 이동)
  • 현재 로그인 뷰 컨트롤러가 메모리에서 사라지는 deinit에서 해당 옵저버를 중앙 센터에서 해제

구현 화면

profile
JUST DO IT

0개의 댓글