본문 바로가기

Project/FirebaseTest

FireBase - 사용자 정보 불러오기 및 사용자 삭제

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에서 해당 사용자의 데이터를 가져오는 메서드입니다.
  • 동작 흐름:
    1. Firebase Auth에서 현재 사용자의 UID를 가져옵니다.
    2. Firestore에서 users 컬렉션 안의 해당 UID 문서를 조회합니다.
    3. 조회 결과(snapshot)에서 데이터를 추출하여 User 객체로 생성합니다.
    4. completion 핸들러를 통해 User 객체 또는 에러를 반환합니다.
public func fetchUser(completion: @escaping (User?, Error?) -> Void) {

 

 

  • 매개변수:
    • completion: 비동기 작업 결과를 호출하는 클로저.
      • 성공 시 User? 객체를 반환.
      • 실패 시 Error? 객체를 반환.
  • 비동기 작업의 구조:
    • 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 핸들러로 반환합니다.

 

최종 흐름

  1. Firebase Auth로부터 사용자 UID를 가져옵니다.
  2. Firestore에서 users 컬렉션의 UID 문서를 조회합니다.
  3. 성공하면 데이터를 추출하여 User 객체를 생성하고 반환합니다.
  4. 실패하면 에러를 반환합니다.

 

🔥 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에서도 삭제하는 메서드입니다.
  • 동작 흐름:
    1. Firestore의 users 컬렉션에서 해당 사용자의 문서를 삭제합니다.
    2. Firestore 삭제가 성공하면 Firebase Authentication에서 해당 사용자를 삭제합니다.
    3. 결과를 completion 핸들러로 전달합니다.

 

public func deleteUser(completion: @escaping (Bool, Error?) -> Void) {
  • 매개변수:
    • completion: 삭제 작업 결과를 처리하는 클로저.
      • 성공 시 Bool로 결과를 반환.
      • 실패 시 Error?로 오류를 반환.

 

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를 반환, 실패 시 에러를 반환합니다.

 

최종 흐름

  1. Firebase Auth에서 로그인된 사용자를 확인합니다.
  2. Firestore에서 users 컬렉션의 사용자 데이터를 삭제합니다.
  3. Firestore 삭제 성공 후, Firebase Authentication에서 사용자를 삭제합니다.
  4. 모든 작업이 성공하면 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에 정의된 메서드로, 사용자의 인증 상태를 확인하고 초기 화면으로 전환하는 역할을 합니다.