포스트

Final (6)

Kakao Firebase 연동

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
func kakaoLoginDidTapped() {
        if AuthApi.hasToken() {
            UserApi.shared.accessTokenInfo { [weak self] _, error in
                if let error = error {
                    print("Token info error: \(error.localizedDescription)")
                    self?.openKakaoService()
                } else {
                    print("Token is valid")
                    self?.loadingInfoDidKakaoAuth()
                }
            }
        } else {
            print("No token, opening Kakao service")
            openKakaoService()
        }
    }
    
    private func openKakaoService() {
        if UserApi.isKakaoTalkLoginAvailable() {
            UserApi.shared.loginWithKakaoTalk { [weak self] oauthToken, error in
                if let error = error {
                    self?.loginPublisher.send(completion: .failure(error))
                    return
                }
                print("KakaoTalk login successful")
                _ = oauthToken
                self?.loadingInfoDidKakaoAuth()
            }
        } else {
            UserApi.shared.loginWithKakaoAccount { [weak self] oauthToken, error in
                if let error = error {
                    self?.loginPublisher.send(completion: .failure(error))
                    return
                }
                print("KakaoAccount login successful")
                _ = oauthToken
                self?.loadingInfoDidKakaoAuth()
            }
        }
    }
    
    private func loadingInfoDidKakaoAuth() {
        UserApi.shared.me { [weak self] kakaoUser, error in
            if let error = error {
                self?.loginPublisher.send(completion: .failure(error))
                return
            }
            guard let uid = kakaoUser?.id else {
                return
            }
            let email = kakaoUser?.kakaoAccount?.email ?? "\(uid)@kakao.com"
            
            
            let userModel = UserModel(uid: String(uid), email: email)
            self?.signInToFirebase(with: userModel)
        }
    }
    
    private func signInToFirebase(with userModel: UserModel) {
            let emailForSignIn = userModel.email
            let passwordForSignIn = userModel.uid
            
            let credential = OAuthProvider.credential(withProviderID: "oidc.kakao.com", accessToken: passwordForSignIn)
            
            Auth.auth().signIn(with: credential) { [weak self] authResult, error in
                if let error = error {
                    self?.loginPublisher.send(completion: .failure(error))
                    return
                }
                
                print("Firebase sign in successful")
                self?.signManager.saveUserData(user: userModel)
                self?.loginPublisher.send(())
            }
        }

    
    private func signUpToFirebase(with userModel: UserModel) {
        let emailForSignUp = userModel.email
        let passwordForSignUp = userModel.uid
        
        Auth.auth().createUser(withEmail: emailForSignUp, password: passwordForSignUp) { [weak self] authResult, error in
            if let error = error {
                self?.loginPublisher.send(completion: .failure(error))
                return
            }
            
            print("Firebase sign up successful")
            self?.signManager.saveUserData(user: userModel)
            self?.loginPublisher.send(())
        }
    }

현재 Error 발생으로 잠시 홀딩…

현재 로그인 상태 확인.

1
2
3
4
5
6
7
8
func configureInitialViewController () {
            var initialVC = UIViewController()
            if Auth.auth().currentUser != nil {
               print(Auth.auth().currentUser)
            } else {
               print("nil")
            }
        }

로그아웃 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// SignManager
func signOut(completion: @escaping (Result<Void, Error>) -> Void) {
        let firebaseAuth = Auth.auth()
        do {
            try firebaseAuth.signOut()
            completion(.success(()))
        } catch let signOutError {
            completion(.failure(signOutError))
        }
    }
    
    // Kakao 로그아웃
    func signOutKakao(completion: @escaping (Error?) -> Void) {
        UserApi.shared.logout { error in
            if let error = error {
                print("DEBUG: Kakao 로그아웃 에러 \(error.localizedDescription)")
            } else {
                print("DEBUG: Kakao 로그아웃 성공")
            }
            completion(error)
        }
    }
    
    // Google 로그아웃
    func signOutGoogle(completion: @escaping (Error?) -> Void) {
        GIDSignIn.sharedInstance.signOut()
        print("DEBUG: Google 로그아웃 성공")
        completion(nil)
    }
    
    // Apple 로그아웃 함수
    func signOutApple(completion: @escaping (Error?) -> Void) {
        let appleIDProvider = ASAuthorizationAppleIDProvider()
        appleIDProvider.getCredentialState(forUserID: "YOUR_USER_ID") { (credentialState, error) in
            switch credentialState {
            case .authorized:
                completion(nil)
            case .revoked:
                completion(nil)
            case .notFound:
                completion(nil)
            default:
                completion(error)
            }
        }
    }
    
    // 로그인된 서비스 확인 및 로그아웃
    func signOutCurrentUser(completion: @escaping (Result<Void, Error>) -> Void) {
        if let user = Auth.auth().currentUser {
            for provider in user.providerData {
                switch provider.providerID {
                case "apple.com":
                    signOutApple { error in
                        if let error = error {
                            completion(.failure(error))
                        } else {
                            self.signOut(completion: completion)
                        }
                    }
                case "google.com":
                    signOutGoogle { error in
                        if let error = error {
                            completion(.failure(error))
                        } else {
                            self.signOut(completion: completion)
                        }
                    }
                case "kakao.com":
                    signOutKakao { error in
                        if let error = error {
                            completion(.failure(error))
                        } else {
                            self.signOut(completion: completion)
                        }
                    }
                default:
                    break
                }
            }
        } else {
            let error = NSError(domain: "FirebaseService", code: -1, userInfo: [NSLocalizedDescriptionKey: "로그인된 사용자가 없습니다."])
            completion(.failure(error))
        }
    }

// VM
 func signOut() {
            signManager.signOutCurrentUser { [weak self] result in
                switch result {
                case .success:
                    self?.logoutPublisher.send()
                case .failure(let error):
                    self?.logoutPublisher.send(completion: .failure(error))
                }
            }
        }

각 메서드에 맞는 로그아웃 함수를 구현.

provider를 통해 로그아웃.

딱히 뭐 적을건 없을듯 하다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.