You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI集成Firebase时Firestore拉取用户数据延迟及导航无动画问题

问题1:用户信息更新延迟

原因

当前逻辑是Firebase Auth状态变更后立刻将signedIn设为true,才异步发起Firestore用户数据请求,导致FirstView已经渲染完成,用户数据返回后才刷新UI,出现视觉延迟。同时登出时没有清空旧的userInfo缓存,切换账号时会先显示上一个用户的信息。

修复步骤

  1. 登出时清空旧用户数据缓存
func signOut(){
    do {
        try authRef.signOut()
        // 新增:清空旧用户数据
        DispatchQueue.main.async {
            self.userInfo = nil
        }
    } catch {
        print(error)
    }
}
  1. 调整监听逻辑,等待用户数据拉取完成后再修改登录状态
func listen(){
    handle = authRef.addStateDidChangeListener({ auth, user in
        print(user?.email ?? "No User Found")
        
        if let user = auth.currentUser {
            self.userIdRef = user.uid
            self.rootInfoCollection = Firestore.firestore().collection("/Users/")
            
            // 拉取到用户数据后再标记为已登录
            self.fetchUserData { [weak self] success in
                DispatchQueue.main.async {
                    self?.signedIn = success
                }
            }
            
        } else {
            DispatchQueue.main.async {
                self.signedIn = false
            }
        }
    })
}
  1. 给用户数据拉取方法添加回调,且确保所有UI更新在主线程执行
func fetchUserData(completion: @escaping (Bool) -> Void){
    db.collection("Users").document("\(userIdRef)").getDocument { document, error in
        guard error == nil, let document = document, document.exists else {
            completion(false)
            return
        }
        
        let data = document.data()
        let uid = data?["uid"] as? UUID ?? UUID()
        let company = data?["company"] as? String ?? ""
        let name = data?["name"] as? String ?? ""
        let admin = data?["admin"] as? Bool ?? false
        let photo = data?["photo"] as? String ?? ""
        
        DispatchQueue.main.async {
            self.userInfo = User(uid: uid, company: company, name: name, admin: admin, photo: photo)
            completion(true)
        }
    }
}
问题2:登录到首页导航过渡生硬

原因

当前是用条件判断直接替换NavigationView的根视图,不是走NavigationLink的push流程,所以没有系统默认的转场动画。

修复方案

方案1:给条件切换添加系统转场动画(修改成本最低)

修改ContentView代码即可:

struct ContentView: View {
    @EnvironmentObject var viewModel: AppViewModel
    
    var body: some View {
        NavigationView {
            Group {
                if viewModel.signedIn {
                     FirstView()
                } else {
                    SignInView()
                        .onAppear(perform: UIApplication.shared.addTapGestureRecognizer)
                        .navigationBarHidden(true)
                }
            }
            // 新增:绑定登录状态变化触发动画
            .animation(.easeInOut, value: viewModel.signedIn)
        }
        .onAppear {
            viewModel.listen()
        }
    }
}

方案2:调整导航结构

将SignInView作为导航根视图,登录成功后调用NavigationLink的push逻辑,可获得和普通页面跳转完全一致的动画效果。

内容的提问来源于stack exchange,提问作者RapsIn4

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 14:00:01