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

Posted

技术标签:

【中文标题】成功登录后 SwiftUI Firebase 身份验证关闭视图【英文标题】:SwiftUI Firebase Authentication dismiss view after successfully login 【发布时间】:2021-07-28 11:32:31 【问题描述】:

我是一名初学者 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】:

您想使用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,您现在可以从任何视图访问用户,此外,这还允许跟踪用户的身份验证状态,这意味着如果他们已登录,那么应用程序将记住。

【讨论】:

感谢快速重播!所以基本上如果 SignInView 嵌套在 InitialView 内部,在 ObservedObject(或环境对象)将发生变化之后,整个 InitialView 将被重建并且条件“if session.isLoggedIn”将再次被触发? @ŁukaszStrzelecki 它将首先检查用户是否已登录,如果已登录,则显示相应的视图。如果用户登录,您的DashboardView() 将显示。

以上是关于成功登录后 SwiftUI Firebase 身份验证关闭视图的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 与 Microsoft 的 Firebase 身份验证

FireBase 登录过程后导航到主屏幕(内容视图)。 (SwiftUI)

Firebase 身份验证登录但成功登录后重定向到主页失败(服务器响应 200)

Firebase 身份验证 swiftui

成功的 Firebase 身份验证后 React Native App 无法导航

处理 SwiftUI 组合应用程序中的 Firebase 身份验证错误