일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 카카오맵클론
- algorithm
- TDD
- unittest
- RxSwift
- 앱의생명주기
- 클린코드
- SWIFT
- Safari Inspector
- Swift코딩테스트
- ios면접
- 리팩터링
- Di
- storekit2
- five lines of code
- 프로그래머스
- ARC
- hackerrank
- 코딩테스트입문
- firebase
- AutoLayout
- RC
- five lines of cdde
- mrc
- alamofire
- IOS
- Swift디자인패턴
- css학습
- UIKit
- firestore
- Today
- Total
샘성의 iOS 개발 일지
[KakaoMap 클론] 4. Firebase에 카카오톡 로그인 유저 정보 저장하기 본문
로그인 한 유저의 검색 기록, 장소별 별점, 즐겨찾기 한 장소 쉽게 저장하고 꺼내볼 수 있도록 Firebase에 저장할 것이다.
이를 위해 'Cocoa Pods'를 사용하여 Firebase를 세팅하고 카카오톡 로그인 유저 데이터를 저장해보자!
배경 : 카카오톡 로그인 구현 완료 된 상태
카카오톡 로그인 구현이 안 된 상태라면, 하단의 게시글을 참고하시면 좋을 것 같습니다.
카카오톡 로그인 구현하기
국민 메신저인 카카오톡 로그인 구현은 필수일 것 같아 구현하면서 기록하려한다. 간단한 Auth만 구현하는 것이기 때문에 스토리보드로 해보려고 한다. 1. 종류 우선, 카카오에서 제공하는 로그
iossammy.tistory.com
1. Firebase 프로젝트 세팅하기
하단의 사이트에 접속 >> '시작하기' 버튼을 눌러 새로운 프로젝트를 생성한다.
Firebase
Firebase is an app development platform that helps you build and grow apps and games users love. Backed by Google and trusted by millions of businesses around the world.
firebase.google.com
원하는 프로젝트명을 기입한 후, 구글 애널리스트 사용 여부 체크를 하면 상단의 이미지와 함께 새 프로젝트 생성이 완료된다.
생성이 완료되면 상단과 같은 화면을 볼 수 있다. iOS 앱을 만드므로 'iOS+'라고 적혀있는 동그라미를 누른다.
이제 각자 프로젝트의 번들 아이디를 사용하여 빈칸을 기입 후, '앱 등록' 버튼을 누른다.
그리고 'GoogleService-Info.plist 다운로드' 버튼을 누르면 하단과 같은 info.plist를 다운받게 된다.
프로젝트에 다운받은 info.plist를 드래그-앤 드롭 하여 집어넣는다.
그리고 Firebase 프로젝트 화면의 '다음' 버튼을 누른다.
주의: 이 때, 파일명이 'GoogleService-Info.plist'인지 잘 확인해야한다. 뒤에 숫자가 붙는다던지.. 다를 경우 실행이 안된다.
이제 Firebase에 필요한 소스파일을 다운받아 프로젝트에 넣어야한다.
SPM(Swift Package Manager)를 사용해도 되지만, 필자는 Cocoa Pods를 사용하여 해당 파일을 프로젝트에 install 할 것이다.
Apple 앱에 Firebase 설치 | Apple 플랫폼용 Firebase
Google I/O 2023에서 Firebase의 주요 소식을 확인하세요. 자세히 알아보기 의견 보내기 Apple 앱에 Firebase 설치 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Swift P
firebase.google.com
pod 'FirebaseAuth'
pod 'FirebaseFirestore'
pod file에 두가지 pod를 리스트에 추가 및 저장한다.
cd 프로젝트 경로 // 프로젝트 경로로 이동
pod install --repo-update // update 된 pod file 다운로드
여러개의 pod file들이 다운받아지는 것을 확인할 수 있다. (오래걸림..)
다 다운 받아졌으면, 프로젝트가 build되는지 확인한다. (오래걸림2222.... 약 4000개 이상의 파일이 빌드되는 것을 볼 수 있다...)
잘 build 된다면, '다음' 버튼을 눌러서 초기화 코드를 추가할 것이다.
Firebase에서 상단과 같은 코드를 추가하라고 제공했지만 @UIApplicationMain만 봐도 예전에 업로드 후 업데이트 되지 않았다는 것을 알 수 있다..^^.. 그래도 코드의 차이는 없기에..
하단의 코드를 그대로 AppDelegate - didFinishLaunchingWithOptions에 넣으면 된다.
import UIKit
import FirebaseCore
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
return true
}
...
2. Firebase Authentication 세팅하기
좌측의 '빌드' >> 'Authentication'을 클릭하여 유저 로그인 및 인증을 관리할 Authentication을 시작할 수 있다.
Firebase에서 제공하는 로그인 제공업체에는 '카카오톡'이 없다.
그러므로 기본 제공업체의 '이메일/비밀번호'를 사용할 예정이다. (클릭하기)
이메일은 '카카오 아이디 이메일', 비밀번호는 '카카오 유저 고유 식별번호'를 사용할 것이다.
3. Firestore 세팅하기
Authentication을 생성한것과 동일하게, 왼쪽에 있는 탭 리스트 중 'Firestore Database'를 눌러서 세팅한다.
이 후, 생성한 Firestore의 규칙을 수정하지 않으면 콘솔창에 하단과 같은 에러를 받을 수 있으니.. 꼭 규칙을 수정해야한다.
error: 'Permission denied: Missing or insufficient permissions.'
false로 되어있는 초록색 부분을 true로 변경하면 끝이다!
4. 로그인 및 회원가입 + Firestore에 유저 정보 저장하기 ( + 소스코드)
Firebase로그인을 담당하는 AuthService라는 구조체를 하나 생성했다.
로직은 간단하다.
- 유저가 로그인 버튼을 누른다.
- 카카오톡으로부터 해당 유저의 카카오톡 이메일, 카카오톡 닉네임, 카카오톡 고유 유저id를 받는다.
(앱 로그인 id == 카카오톡 이메일 / 앱 로그인 비밀번호 == 카카오톡 고유 유저 id) - 해당 유저가 이미 존재하는 유저인지 체크한다. (로그인 시도를 하면, 존재하지 않는 유저인 경우 에러가 발생한다. 이 때 회원가입 코드를 넣으면 된다)
>> 이미 존재하는 유저인 경우: 로그인 진행 // 존재하지 않는 유저인 경우: 회원가입 진행 - 로그인 혹은 회원가입이 완료되면, UserDefaults에 '유저 이메일, 유저 닉네임, 유저 uid, 카카오 로그인 여부' 저장
- 모든 작업이 끝나면 completion 블럭에 이후 처리할 작업 정의하기
(필자는 노티피케이션 센터에 로그인 된 것을 알리고, 해당 알림을 받는 객체들이 로그인 여부에 따라 다음 작업을 할 수 있도록 했다)
* Firebase 로그인을 담당하는 AuthService 구조체 *
import Foundation
import FirebaseAuth
// 필요한 유저 정보 캡슐화
struct AuthCredentials {
let email: String
let nickName: String
let password: String
let isKakaoLogin: Bool
}
typealias AuthDataResultCallback = (AuthDataResult?, Error?) -> Void
struct AuthService {
/// 기존에 없는 새로운 유저 등록
static func registerUser(userInfo credentials: AuthCredentials, completion: @escaping () -> Void) {
Auth.auth().createUser(withEmail: credentials.email,
password: credentials.password) { (result, error) in
if let error = error {
print("AuthService ERROR : \(error.localizedDescription)")
return
}
guard let userUID = result?.user.uid else { return }
// 유저 이메일에 해당되는 다큐먼트에 들어갈 컬렉션 형태의 데이터
let data = ["email": credentials.email,
"nickName": credentials.nickName,
"isKakaoLogin": credentials.isKakaoLogin,
"uid": userUID] as [String : Any]
// 'uses' 컬렉션에 유저 이메일을 id로 새로운 다큐먼트 생성 + 다큐먼트에 생성한 컬렉션 데이터 넣기
Firestore.firestore().collection("users").document(credentials.email).setData(data) { error in
if let _ = error {
print("새로운 유저 생성하기 실해")
return
}
// UserDefaults에 로그인 된 유저 정보 저장
UserDefaultsManager.shared.setUserInfo(nickName: credentials.nickName,
email: credentials.email,
uid: userUID,
isKakaoLogin: credentials.isKakaoLogin)
completion()
}
}
}
/// 기존 유저 로그인
static func logUserIn(withEmail email: String, password: String, completion: AuthDataResultCallback?) {
Auth.auth().signIn(withEmail: email, password: password, completion: completion)
}
}
* UserDefaults를 담당하는 구조체 *
struct UserDefaultsManager {
static let shared = UserDefaultsManager()
private init() { }
func setUserInfo(nickName: String, email: String, uid: String, isKakaoLogin: Bool) {
UserDefaults.standard.set(nickName, forKey: "name")
UserDefaults.standard.set(email, forKey: "email")
UserDefaults.standard.set(uid, forKey: "uid")
UserDefaults.standard.set(isKakaoLogin, forKey: "isKakaoLogin")
}
}
* 카카오톡 로그인 버튼에 연결된 target Action 함수 *
@objc private func kakaoLoginButtonTapped() {
// 로그인 된 경우 -> 로그아웃
// 로그인 안 된 경우 -> 로그인
if UserApi.isKakaoTalkLoginAvailable() {
UserApi.shared.loginWithKakaoTalk { [weak self] token, error in
if let error = error {
print(error)
return
}
print("카카오 로그인 성공")
_ = token
// 로그인 된 카카오톡 정보 노티피케이션 센터에 등록 및 메뉴에 있는 프로필 세팅하기
// firebase에 해당 카카오톡 아이디로 회원가입 유무 확인 후, 없으면 가입하고 있으면 로그인시키기
self?.setFirebaseForKakaoTalkLogin()
}
}
print("카카오 로그인 구현하기")
}
* 카카오톡 로그인 된 유저 정보로 Firebase에 로그인 및 회원가입 후, 완료되면 NotificationCenter에 알리는 메서드
private func setFirebaseForKakaoTalkLogin() {
UserApi.shared.me {[weak self] user, error in
guard let user = user,
let email = user.kakaoAccount?.email,
let nickName = user.kakaoAccount?.profile?.nickname,
let password = user.id,
error == nil else {
print(error!)
return
}
let kakaoAuthCredentials = AuthCredentials(email: email,
nickName: nickName,
password: String(password),
isKakaoLogin: true)
AuthService.logUserIn(withEmail: email, password: String(password)) { result, error in
// 이미 존재하는 유저인지 확인 (로그인 실패: 유저 존재 X, 로그인 성공: 유저 존재 O)
guard let result = result,
let email = result.user.email,
error == nil else {
// 로그인 실패, 유저 존재 X
print("새로운 유저 회원가입 필요")
AuthService.registerUser(userInfo: kakaoAuthCredentials) {
NotificationManager.postloginNotification(name: nickName,
userEmail: email,
profileImageURL: user.kakaoAccount?.profile?.profileImageUrl,
isKakaoLogin: true)
self?.cancelButtonTapped()
}
return
}
// 로그인 성공, 유저 존재 O
print("기존 존재하는 유저로 로그인하기")
UserDefaultsManager.shared.setUserInfo(nickName: nickName,
email: email,
uid: result.user.uid,
isKakaoLogin: true)
NotificationManager.postloginNotification(name: nickName,
userEmail: email,
profileImageURL: user.kakaoAccount?.profile?.profileImageUrl,
isKakaoLogin: true)
self?.cancelButtonTapped()
}
}
}
Authentication에 성공적으로 카카오톡 아이디를 이용해 로그인이 된 것을 확인할 수 있다.
추가적으로 필요한 유저의 정보들 또한 Firestore에 저장된것을 확인할 수 있다.
끝-
'iOS > UiKit' 카테고리의 다른 글
[iOS 16.4~] Inspector로 iOS 앱 내 띄운 웹뷰 디버깅 하기 (1) | 2024.03.27 |
---|---|
[KakaoMap 클론] 5. 장소 즐겨찾기 기능 추가하기 (feat. Firestore) (0) | 2023.06.11 |
UIApplication 객체의 컨트롤러 역할은 어디에 구현해야 하는가? (0) | 2023.06.08 |
UIImage를 원하는 사이즈로 조절하는 법 (0) | 2023.06.08 |
[KakaoMap 클론] 3. 지도 위에 경로 그리기 (0) | 2023.05.31 |