嗨所有我使用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)
}
}
}
}
现在,当用户登录时,他的名字立即出现,但当我关闭应用程序并重新打开它时,显示用户名的延迟似乎仍然发生,可能是因为他正在等待用户状态从未定义更改为已验证..我该怎么解决?
1条答案
按热度按时间h79rfbju1#
假设您从Firestore加载用户名,并且这是一个异步操作,那么在它可用之前的延迟似乎是可以预期的。
对此没有解决办法:加载数据只是需要时间。您的代码需要决定在加载数据时向用户显示什么,例如。显示“正在加载……”或某种动画。