public func fetchUser(completion: @escaping (User?, Error?) -> Void) {
guard let userUID = Auth.auth().currentUser?.uid else { return }
let db = Firestore.firestore()
db.collection("users")
.document(userUID)
.getDocument { snapshot, error in
if let error = error {
completion(nil, error)
return
}
if let snapshot = snapshot,
let snapshotData = snapshot.data(),
let username = snapshotData["username"] as? String,
let email = snapshotData["email"] as? String {
let user = User(username: username, email: email, userUID: userUID)
completion(user, nil)
}
}
}
public func deleteUser(completion: @escaping (Bool, Error?) -> Void) {
guard let user = Auth.auth().currentUser else {
completion(false, NSError(domain: "", code: 401, userInfo: [NSLocalizedDescriptionKey: "No user is logged in."]))
return
}
let db = Firestore.firestore()
let userUID = user.uid
// Firestore 데이터 삭제
db.collection("users").document(userUID).delete { error in
if let error = error {
completion(false, error)
return
}
// Firebase Authentication 사용자 삭제
user.delete { error in
if let error = error {
completion(false, error)
return
}
completion(true, nil) // 성공
}
}
}
fetchUser 메서드
- 현재 Firebase Authentication에 로그인된 사용자의 UID를 기반으로 Firestore에서 해당 사용자의 데이터를 가져오는 메서드입니다.
- 동작 흐름:
- Firebase Auth에서 현재 사용자의 UID를 가져옵니다.
- Firestore에서 users 컬렉션 안의 해당 UID 문서를 조회합니다.
- 조회 결과(snapshot)에서 데이터를 추출하여 User 객체로 생성합니다.
- completion 핸들러를 통해 User 객체 또는 에러를 반환합니다.
public func fetchUser(completion: @escaping (User?, Error?) -> Void) {
- 매개변수:
- completion: 비동기 작업 결과를 호출하는 클로저.
- 성공 시 User? 객체를 반환.
- 실패 시 Error? 객체를 반환.
- completion: 비동기 작업 결과를 호출하는 클로저.
- 비동기 작업의 구조:
- Firebase Firestore에서 데이터를 가져오는 작업이 비동기로 수행됩니다.
- 결과는 클로저(completion)로 처리됩니다.
guard let userUID = Auth.auth().currentUser?.uid else { return }
- Firebase Auth에서 현재 로그인한 사용자의 UID를 가져옵니다.
- Auth.auth().currentUser: 현재 로그인한 사용자 객체.
- uid: Firebase에서 사용자를 식별하는 고유 문자열.
- 만약 사용자가 로그인하지 않았다면 메서드가 바로 종료됩니다(return).
let db = Firestore.firestore()
- Firestore 데이터베이스 인스턴스를 초기화합니다.
- Firestore.firestore()를 호출하면 Firestore와 연결된 기본 데이터베이스 객체를 반환합니다.
db.collection("users")
.document(userUID)
.getDocument { snapshot, error in
- Firestore의 users 컬렉션에서 userUID에 해당하는 문서를 가져옵니다.
- collection("users"): Firestore의 users 컬렉션을 지정.
- document(userUID): 해당 컬렉션에서 특정 문서를 선택 (userUID가 문서 ID).
- getDocument: 문서를 비동기로 가져옵니다.
- 결과:
- snapshot: Firestore에서 가져온 DocumentSnapshot 객체.
- error: 오류 객체.
- 결과:
if let error = error {
completion(nil, error)
return
}
- Firestore에서 문서를 가져오는 중에 오류가 발생하면 completion(nil, error)를 호출하고 종료합니다.
if let snapshot = snapshot,
let snapshotData = snapshot.data(),
let username = snapshotData["username"] as? String,
let email = snapshotData["email"] as? String {
- 성공적으로 snapshot을 가져왔을 경우 실행됩니다.
- snapshot: DocumentSnapshot 객체로, Firestore 문서 데이터를 포함.
- snapshot.data(): 문서의 데이터를 딕셔너리 형태로 반환.
- ["username": "JohnDoe", "email": "johndoe@example.com"] 형태.
- 데이터를 추출하고 타입 확인을 통해 변수에 저장 (as? String).
let user = User(username: username, email: email, userUID: userUID)
completion(user, nil)
- User 객체를 생성하고 completion 핸들러로 반환합니다.
최종 흐름
- Firebase Auth로부터 사용자 UID를 가져옵니다.
- Firestore에서 users 컬렉션의 UID 문서를 조회합니다.
- 성공하면 데이터를 추출하여 User 객체를 생성하고 반환합니다.
- 실패하면 에러를 반환합니다.
🔥 snapshot이란 무엇인가? 🔥
snapshot은 Firestore에서 데이터를 읽을 때 반환되는 객체입니다. 여기서는 DocumentSnapshot 객체입니다.
- snapshot의 역할:
- Firestore에서 특정 문서를 읽은 결과를 포함합니다.
- 문서의 데이터, ID, 존재 여부와 같은 정보를 제공합니다.
- snapshot.data() 메서드를 호출하여 문서의 데이터를 딕셔너리 형태로 가져올 수 있습니다.
if let snapshot = snapshot,
let snapshotData = snapshot.data() {
// snapshotData는 Firestore 문서의 데이터를 딕셔너리로 반환합니다.
let username = snapshotData["username"] as? String
}
- snapshot 상태 확인:
- snapshot.exists: 문서가 존재하는지 확인하는 Bool 값.
- snapshot.data(): 문서 데이터를 딕셔너리로 가져오는 메서드.
- snapshot.documentID: 문서 ID를 반환.
간단히 말해:
snapshot은 Firestore에서 가져온 문서의 정보를 포함하는 객체이며, 이를 통해 데이터를 읽고 문서의 상태를 확인할 수 있습니다.
deleteUser 메서드:
- 현재 로그인된 사용자의 데이터를 Firestore에서 삭제하고, Firebase Authentication에서도 삭제하는 메서드입니다.
- 동작 흐름:
- Firestore의 users 컬렉션에서 해당 사용자의 문서를 삭제합니다.
- Firestore 삭제가 성공하면 Firebase Authentication에서 해당 사용자를 삭제합니다.
- 결과를 completion 핸들러로 전달합니다.
public func deleteUser(completion: @escaping (Bool, Error?) -> Void) {
- 매개변수:
- completion: 삭제 작업 결과를 처리하는 클로저.
- 성공 시 Bool로 결과를 반환.
- 실패 시 Error?로 오류를 반환.
- completion: 삭제 작업 결과를 처리하는 클로저.
guard let user = Auth.auth().currentUser else {
completion(false, NSError(domain: "", code: 401, userInfo: [NSLocalizedDescriptionKey: "No user is logged in."]))
return
}
- Firebase Auth에서 현재 로그인된 사용자를 가져옵니다.
- 사용자가 없다면 401 Unauthorized 에러를 반환하고 종료합니다.
let db = Firestore.firestore()
let userUID = user.uid
- Firestore 인스턴스를 초기화하고, 현재 사용자의 UID를 가져옵니다.
db.collection("users").document(userUID).delete { error in
- Firestore에서 users 컬렉션의 UID 문서를 삭제합니다.
- 콜백:
- 성공: error가 nil.
- 실패: error가 발생.
- 콜백:
if let error = error {
completion(false, error)
return
}
- Firestore 삭제 중 오류가 발생하면 에러를 반환하고 종료합니다.
user.delete { error in
if let error = error {
completion(false, error)
return
}
completion(true, nil)
}
- Firestore에서 문서를 삭제한 뒤, Firebase Authentication에서도 사용자를 삭제합니다.
- 성공 시 true를 반환, 실패 시 에러를 반환합니다.
최종 흐름
- Firebase Auth에서 로그인된 사용자를 확인합니다.
- Firestore에서 users 컬렉션의 사용자 데이터를 삭제합니다.
- Firestore 삭제 성공 후, Firebase Authentication에서 사용자를 삭제합니다.
- 모든 작업이 성공하면 true를 반환하고, 실패하면 에러를 반환합니다.
HomeController
@objc private func didTapDelete() {
AutheService.shared.deleteUser { success, error in
if success {
print("회원 탈퇴 성공!")
// 탈퇴 후 초기 화면으로 이동
if let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate {
sceneDelegate.checkAuthentication()
}
} else if let error = error {
print("회원 탈퇴 실패: \(error.localizedDescription)")
}
}
}
이 코드는 사용자가 "삭제" 버튼을 눌렀을 때 호출되는 회원 탈퇴 기능을 구현한 메서드입니다.
AuthService.shared.deleteUser { success, error in
- AuthService.shared.deleteUser:
- AuthService는 싱글톤 패턴으로 구현된 클래스나 구조체입니다.
- deleteUser 메서드를 호출하여 회원 탈퇴를 처리합니다.
- completion:
- success: 회원 탈퇴 성공 여부를 나타내는 Bool.
- error: 회원 탈퇴 중 발생한 오류를 나타내는 Error?.
if let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate {
sceneDelegate.checkAuthentication()
}
- 회원 탈퇴 후 초기 화면으로 이동하는 코드.
- UIApplication.shared.connectedScenes.first:
- 앱의 활성화된 Scene 객체를 가져옵니다.
- delegate:
- Scene의 델리게이트를 가져옵니다. 여기서는 SceneDelegate로 캐스팅합니다.
- checkAuthentication:
- SceneDelegate에 정의된 메서드로, 사용자의 인증 상태를 확인하고 초기 화면으로 전환하는 역할을 합니다.
- UIApplication.shared.connectedScenes.first:
'Project > FirebaseTest' 카테고리의 다른 글
FireBase - 회원 정보 불러오기 (0) | 2024.12.05 |
---|---|
FireBase - 회원가입할 때 프로필 이미지 포함 (1) | 2024.12.05 |
FireBase - 유효성 검사 + 사용자 등록 (0) | 2024.12.03 |
FireBase - 로그인과 로그아웃 처리하는 메서드 정의 (1) | 2024.12.03 |
FireBase - 사용자 등록 기능 (0) | 2024.12.03 |