본문 바로가기

프로젝트/Twitter Clone App (w∕Firebase)

12. DB와 연결하기 #1

DB와 연결하기 #1
Link UserData to SideMenu


Link UserData to SideMenu
| AuthViewModel

class AuthViewModel: ObservableObject {
    @Published var userSession: FirebaseAuth.User?
    @Published var didAuthenticateUser = false
    @Published var currentUser: User?

    private var tempUserSession: FirebaseAuth.User?
    private let service = UserService()

    init() {
        self.userSession = Auth.auth().currentUser
        fetchUser()
    }

현재 접속 중인 유저를 확인하기 위해 currentUser 인스턴스를 생성한다.
형식은 '11. 기능 구현하기 #3'에서 정의한 User다.

Link UserData to SideMenu
| UserService

before

struct UserService {
    func fetchUser(withUid uid: String) {
        Firestore.firestore().collection("users").document(uid).getDocument { snapshot, _ in
            guard let snapshot = snapshot else {
                return
            }

            guard let user = try? snapshot.data(as: User.self) else {
                return
            }
        }
    }
}

after

struct UserService {
    func fetchUser(withUid uid: String, completion: @escaping(User) -> Void) {
        Firestore.firestore().collection("users").document(uid).getDocument { snapshot, _ in
            guard let snapshot = snapshot else {
                return
            }

            guard let user = try? snapshot.data(as: User.self) else {
                return
            }

            completion(user)
        }
    }
}

fetchUser를 통해 가져온 데이터는 completionHandler로 전달할 수 있도록 코드를 수정한다.
parameter에 completion이 추가됐고, '@escaping'을 지정한다.
이 과정을 통해 정의한 메서드는 completion을 호출하는 것 만으로 completionHandler에 결과를 전달할 수 있다.

Link UserData to SideMenu
| AuthViewModel

class AuthViewModel: ObservableObject {
    @Published var userSession: FirebaseAuth.User?
    @Published var didAuthenticateUser = false
    @Published var currentUser: User?

    private var tempUserSession: FirebaseAuth.User?
    private let service = UserService()

    init() {
        self.userSession = Auth.auth().currentUser
        fetchUser()
    }

    .
    .
    .

    func fetchUser() {
        guard let uid = self.userSession?.uid else {
            return
        }

        service.fetchUser(withUid: uid) { user in
            self.currentUser = user
        }
    }
}

AuthViewModel의 currentUser에 fetchUser의 결과를 저장한다.

Link UserData to SideMenu
| SideMenu

struct SideMenuView: View {
    @EnvironmentObject var authViewModel: AuthViewModel

    var body: some View {
        if let user = authViewModel.currentUser {
            VStack(alignment: .leading, spacing: 32) {
                VStack(alignment: .leading) {
                    Circle()
                        .frame(width: 48, height: 48)

                    VStack(alignment: .leading, spacing: 4) {
                        Text(user.fullname)
                            .font(.headline)

                        Text("@\(user.username)")
                            .font(.caption)
                            .foregroundColor(.gray)
                    }

                    UserStatsView()
                        .padding(.vertical)
                }
                .padding(.leading)

                ForEach(SideMenuViewModel.allCases, id: \.rawValue) { viewModel in
                    if viewModel == .profile {
                        NavigationLink(destination: ProfileView()) {
                            SideMenuRowView(viewModel: viewModel)
                        }
                    } else if viewModel == .logout {
                        Button {
                            authViewModel.signOut()
                        } label: {
                            SideMenuRowView(viewModel: viewModel)
                        }
                    } else {
                        SideMenuRowView(viewModel: viewModel)
                    }
                }

                Spacer()
            }
            .background(Color.white)
        }
    }
}

SideMenu의 모든 View를 'if-let'을 사용해 분기한다.
currentUser를 binding 불가능한 경우 SideMenu를 표시할 수 없다.

지금 당장 표시할 수 있는 데이터를 표시해 보자.
fullname과 username을 형식에 맞게 전달하면 된다.

'프로젝트 > Twitter Clone App (w∕Firebase)' 카테고리의 다른 글

14. 버그 수정 #1  (0) 2023.01.11
13. DB와 연결하기 #2  (0) 2023.01.10
11. 기능 구현하기 #3  (0) 2022.12.22
10. 기능 구현하기 #2  (0) 2022.12.20
09. 기능 구현하기 #1  (0) 2022.12.13