成功登录后,SwiftUI Firebase 身份验证关闭视图

时间:2021-07-28 11:32:31

标签: swift firebase swiftui firebase-authentication

我是 iOS 开发初学者,我的第一个应用程序有问题。我正在使用 Firebase 作为我的应用程序的后端,并且我已经登录并启用了已实现的方法。我的问题是在 Auth.auth().signIn 方法完成后关闭 LoginView。当我通过在 isActive 中设置 ObservableObject 使用 NavigationLink 时,我设法做到了这一点:

NavigationLink(destination: DashboardView(), isActive: $isUserLogin) { EmptyView() }

它按预期工作:当应用程序结束登录过程屏幕将进入下一个视图时 - 仪表板。

但我不想使用 NavigationLink 并创建额外的步骤,我只想使用以下方法返回仪表板:

self.presentationMode.wrappedValue.dismiss()

在这种情况下,我不知道如何强制应用程序等待方法 loginUser() 结束。这是我的代码现在的样子:

if loginVM.loginUser() {                    
    appSession.isUserLogin = true
    self.presentationMode.wrappedValue.dismiss()
}

我尝试使用闭包,但它不起作用或者我做错了什么。

非常感谢!

1 个答案:

答案 0 :(得分:1)

您想使用 AuthStateDidChangeListenerHandle@EnvrionmentObject,如下所示:

class SessionStore: ObservableObject {
    var handle: AuthStateDidChangeListenerHandle?
    @Published var isLoggedIn = false
    @Published var userSession: UserModel? { didSet { self.willChange.send(self) }}
    var willChange = PassthroughSubject<SessionStore, Never>()
    
    func listenAuthenticationState() {
        handle = Auth.auth().addStateDidChangeListener({ [weak self]  (auth, user) in
            if let user = user {
                let firestoreUserID = API.FIRESTORE_DOCUMENT_USER_ID(userID: user.uid)
                firestoreUserID.getDocument { (document, error) in
                    if let dict = document?.data() {
                        //Decoding the user, you can do this however you see fit
                        guard let decoderUser = try? UserModel.init(fromDictionary: dict) else {return}
                        self!.userSession = decoderUser
                    }
                }
                self!.isLoggedIn = true
            } else {
                self!.isLoggedIn = false
                self!.userSession = nil
            }
        })
    }
    
    func logOut() {
        do {
            try Auth.auth().signOut()
            print("Logged out")
        } catch let error {
            debugPrint(error.localizedDescription)
        }
    }
    
    func unbind() {
        if let handle = handle {
            Auth.auth().removeStateDidChangeListener(handle)
        }
    }
    
    deinit {
        print("deinit - seession store")
    }
}

然后简单地按照以下方式做一些事情:

struct InitialView: View {
    @EnvironmentObject var session: SessionStore
    func listen() {
        session.listenAuthenticationState()
    }
    var body: some View {
        ZStack {
            Color(SYSTEM_BACKGROUND_COLOUR)
                .edgesIgnoringSafeArea(.all)
            Group {
                if session.isLoggedIn {
                   DashboardView()
                } else if !session.isLoggedIn {
                    SignInView()
                }
            }
        }.onAppear(perform: listen)
    }
}

然后在您的应用程序文件中,您将拥有:

  InitialView()
    .environmentObject(SessionStore())

通过使用@EnvironmentObject,您现在可以从任何视图访问用户,此外,这还允许跟踪用户的身份验证状态,这意味着如果他们已登录,则应用程序将记住。