【发布时间】:2021-12-19 02:13:58
【问题描述】:
上下文:我正在尝试使用 firebase 身份验证和 firestore 来获取用户的数据。我遇到的问题是视图是在完全获取数据之前呈现的,这显然会导致应用程序崩溃。话虽如此,我在我的应用委托中使用了 Firebase 身份验证侦听器,以确保在获取用户数据之前对用户进行身份验证(这也在应用委托中完成,如下所示)
应用委托sn-p
class AppDelegate: NSObject, UIApplicationDelegate {
var handle: AuthStateDidChangeListenerHandle?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
self.handle = Auth.auth().addStateDidChangeListener { (auth, user) in
if (user != nil){
print("UserAuthentication User authenticated in delegate")
DatabaseDelegate().getUserInfo(UID: user!.uid, withCompletionHandler: {
print("got user data")
})
} else {
print(" UserAuthentication User not authenticated in delegate")
try! Auth.auth().signOut()
}
}
return true
}
这是我正在查询并希望在数据加载完成时监听的数据库代码:
class DatabaseDelegate: ObservableObject {
@Published var userDataLoaded = Bool()
func getUserInfo(UID: String, withCompletionHandler completionHandler: @escaping () -> Void) {
database.collection("Users").document(UID).getDocument { (document, error) in
if let document = document, document.exists {
let data = document.data()!
guard let UID = data["UUID"] as? String else { return }
guard let Name = data["Name"] as? String else { return }
guard let PhoneNumber = data["PhoneNumber"] as? String else { return }
guard let StripeID = data["StripeID"] as? String else { return }
self.userDataLoaded = true
UserData.append(User(UID: UID, Name: Name, PhoneNumber: PhoneNumber, StripeID: StripeID, PurchasedContent: ["TEMP": true]))
completionHandler()
}
}
}
}
这是我要根据上面的 userDataLoaded 更新的 SwiftUI 视图:
struct MainViewDelegate: View {
//MARK: VARIABLES
@State var showAnimation = true
@State var locationHandler = LocationHandler()
@ObservedObject var databaseDelegate = DatabaseDelegate()
init(){
//Check and enable user location
locationHandler.requestAuthorisation()
}
var body: some View {
VStack {
//Check if data has finished loading, if not, show loading. Listen for changes when the data is finished loading and then present the tab view when it is.
switch databaseDelegate.userDataLoaded {
case true:
TabView {
HomeView()
.tabItem {
Label("Home", systemImage: "house")
}
CheckoutView()
.tabItem {
Label("Services", systemImage: "bag")
}
SettingsView()
.tabItem {
Label("Settings", systemImage: "gearshape")
}
}
case false:
Text("Loading data")
}
}
}
}
在此先感谢您。我是 swiftui 新手(从 uikit 过渡),我花了太多时间试图解决这个愚蠢的问题
【问题讨论】:
-
请修剪您的代码,以便更容易找到您的问题。请按照以下指南创建minimal reproducible example。