Firebase用户数据显示延迟- SwiftUI

piv4azn7  于 2023-05-18  发布在  Swift
关注(0)|答案(1)|浏览(199)

嗨所有我使用Firebase登录在应用程序
一切似乎都工作得很完美,但我有一个问题,显示用户数据时登录。
登录后,用户被重定向到他的 Jmeter 板,并在标签中显示他的名字。我注意到,一旦显示 Jmeter 板,显示用户名称就会有延迟。
我实现了所有的异步函数,并专门使用了@MainActor来避免这些延迟,所以我不知道为什么会发生这种延迟。
谁能帮我弄清楚如何解决这个问题?

@main
struct TestApp: App {
    
    @StateObject private var authManager = FirebaseAuthManager()
    
    init() { FirebaseApp.configure() }
    
    var body: some Scene {
        WindowGroup {
            switch authManager.userStatus {
            case .undefined, .notAuthenticated :
                SignInView()
                    .environmentObject(authManager)
            case .authenticated:
                DashboardView()
                    .environmentObject(authManager)
            }
        }
    }
}

FirebaseAuthManager.swift

import Foundation
import FirebaseAuth
import FirebaseFirestore
import FirebaseFirestoreSwift

enum AuthStatus { case undefined, notAuthenticated, authenticated }

class FirebaseAuthManager: ObservableObject {
    private let userCollection = "Users"
    @Published var userStatus: AuthStatus = .undefined
    @Published var user: FirestoreModel.User = .init (
        name: .init(firstName: "", lastName: ""),
        accountDetails: .init(emailAddress: "", uid: "")
    )
    
    init() { checkUserStatus() }
}

extension FirebaseAuthManager {
    func checkUserStatus() {
        let listener = Auth.auth().addStateDidChangeListener { result, user in
            guard user != nil else { return self.userStatus = .notAuthenticated }
            self.userStatus = .authenticated
            self.fetchUserInfo(userID: user!.uid)

        }
        Auth.auth().removeStateDidChangeListener(listener)
    }
}

// MARK: - Authentication Function
    
extension FirebaseAuthManager {
    
    @MainActor
    func logout() throws {
        do { try Auth.auth().signOut() }
    }
    
    @MainActor
    func signUp(email: String, password: String, name: FirestoreModel.User.Name) async throws {
        let account = try await Auth.auth().createUser(withEmail: email, password: password)
        let userInfo = FirestoreModel.User(name: .init(firstName: name.firstName, lastName: name.lastName), accountDetails: .init(emailAddress: email, uid: account.user.uid))
        let reference = Firestore.firestore()
                
        do {
            self.user = try await reference.collection(userCollection).document(account.user.uid).getDocument(as: FirestoreModel.User.self)
        } catch {
            
            if error._code == 4865 {
                try reference.collection(userCollection).document(account.user.uid).setData(from: userInfo)
                self.user = userInfo
            }
            else {
                throw error
            }
        }
    }
    
    @MainActor
    @discardableResult
    func signIn(email: String, password: String) async throws -> AuthDataResult {
        try await Auth.auth().signIn(withEmail: email, password: password)
    }
}

// MARK: - Manage Data
extension FirebaseAuthManager {
func fetchUserInfo(userID: String)   {      
    let reference = Firestore.firestore().collection(self.userCollection).document(userID)
    reference.getDocument(as: FirestoreModel.User.self) { result in
        switch result {
        case .success(let user) :
            self.user = user
        case .failure(let error) :
            print(error.localizedDescription)
        }
     }
  }
}

Dashboard.swift

import SwiftUI
import Firebase

struct DashboardView: View {
    @EnvironmentObject private var authManager: FirebaseAuthManager

    var body: some View {
        
        NavigationView {
            VStack {
                Text("Benvenuto " + authManager.user.name.firstName + "!")
            }
            .navigationTitle("Dashboard")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Esci".uppercased()) {
                        logout()
                    }
                    .font(.callout).bold()
                }
            }
        }
    }
}

extension DashboardView {
    private func logout() {
        Task {
            do {
                try authManager.logout()
            } catch {
                print(error.localizedDescription)
            }
        }
    }
}

更新

我更新了代码,避免从firestore异步获取数据,所以我替换了

extension FirebaseAuthManager {
    @MainActor
    func fetchUserInfo(userID: String) async throws {
        let reference = Firestore.firestore()
        let path = reference.collection(userCollection).document(userID)
        self.user = try await path.getDocument(as: FirestoreModel.User.self)
    }
}

用这个..

extension FirebaseAuthManager {
    func fetchUserInfo(userID: String)   {      
        let reference = Firestore.firestore().collection(self.userCollection).document(userID)
        reference.getDocument(as: FirestoreModel.User.self) { result in
            switch result {
            case .success(let user) :
                self.user = user
            case .failure(let error) :
                print(error.localizedDescription)
            }
        }
    }
}

现在,当用户登录时,他的名字立即出现,但当我关闭应用程序并重新打开它时,显示用户名的延迟似乎仍然发生,可能是因为他正在等待用户状态从未定义更改为已验证..我该怎么解决?

h79rfbju

h79rfbju1#

假设您从Firestore加载用户名,并且这是一个异步操作,那么在它可用之前的延迟似乎是可以预期的。
对此没有解决办法:加载数据只是需要时间。您的代码需要决定在加载数据时向用户显示什么,例如。显示“正在加载……”或某种动画。

相关问题