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 라이센스를 따릅니다.