处理 SwiftUI Combine 应用程序中的 Firebase Auth 错误
Handling Firebase Auth error in SwiftUI Combine app
我有一个应用程序,用户可以在其中使用 Firebase 进行注册和登录。但是,我似乎无法提醒用户视图中的任何错误。
首先我们有一个 UserStore,它是一个 ObservableObject
,在 SceneDelegate
中设置视图时被初始化为 EnvironmentObject
.
let appView = AppView().environmentObject(userStore)
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: appView)
self.window = window
window.makeKeyAndVisible()
}
然后我们像这样注册或登录到视图。
在视图中
self.userStore.logIn(email: self.email, password: self.password)
self.isLoggingIn = true
if self.userStore.failedToLogin {
self.isLoggingIn = false
self.alertTitle = "There seems to be a problem"
self.alertBody = self.userStore.errorMessage
self.showingAlert = true
}
然后实际方法应该更新 UserStore 属性 值,然后更新视图并显示警报,但是,情况并非如此。
登录
// Session Properties
@Published var isLoggedIn = false {didSet{didChange.send() }}
@Published var isNewUser = false {didSet{didChange.send() }}
@Published var failedToCreateAccount = false {didSet{didChange.send() }}
@Published var failedToLogin = false {didSet{didChange.send() }}
@Published var errorMessage = "" {didSet{didChange.send() }}
init () {
handle = Auth.auth().addStateDidChangeListener { (auth, user) in
if let user = user {
self.session = user
self.isLoggedIn = true
//Change isNewUser is user document exists?
} else {
self.session = nil
self.isLoggedIn = false
}
}
}
func logIn(email: String, password: String) {
Auth.auth().signIn(withEmail: email, password: password) { [weak self] user, error in
print("Signed In")
if(error != nil) {
print("Failed to login")
self!.failedToLogin = true
self!.errorMessage = ("\(String(describing: error))")
print(error!)
return
} else if error == nil {
print("Success Logging In")
}
}
}
AppView 根据用户是否登录决定加载哪个视图。
AppView
if !userStore.isLoggedIn {
LoginView().transition(.opacity)
}
if userStore.isLoggedIn {
ContentView().transition(.opacity)
}
未显示 Atm 错误消息;登录视图也在主视图之前不久显示。
如何在视图中正确显示错误消息?
Firebase API 是异步的,因为它们通过互联网访问远程系统,这需要一点时间。顺便说一句,这同样适用于访问本地磁盘。 blog post 对此进行了更详细的解释。
因此,userStore.login
是一个异步过程。 IE。对 if self.userStore.failedToLogin
的调用在 userStore.login
returns 之前执行。因此,userStore.failedToLogin
仍然是false
,条件语句中的代码永远不会执行。
有两种解决方法:
- 在
userStore.logIn
上实现尾随闭包,并将显示错误的代码移至闭包
- 创建
userStore.failedToLogin
发布者并订阅您的快讯的可见性
使用 Combine Firebase:https://github.com/rever-ai/CombineFirebase
这是围绕 firebase api 的 combine-swiftui 包装器,因此您可以对 firebase 使用 swift-ui 发布者模式。
我有一个应用程序,用户可以在其中使用 Firebase 进行注册和登录。但是,我似乎无法提醒用户视图中的任何错误。
首先我们有一个 UserStore,它是一个 ObservableObject
,在 SceneDelegate
中设置视图时被初始化为 EnvironmentObject
.
let appView = AppView().environmentObject(userStore)
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: appView)
self.window = window
window.makeKeyAndVisible()
}
然后我们像这样注册或登录到视图。
在视图中
self.userStore.logIn(email: self.email, password: self.password)
self.isLoggingIn = true
if self.userStore.failedToLogin {
self.isLoggingIn = false
self.alertTitle = "There seems to be a problem"
self.alertBody = self.userStore.errorMessage
self.showingAlert = true
}
然后实际方法应该更新 UserStore 属性 值,然后更新视图并显示警报,但是,情况并非如此。
登录
// Session Properties
@Published var isLoggedIn = false {didSet{didChange.send() }}
@Published var isNewUser = false {didSet{didChange.send() }}
@Published var failedToCreateAccount = false {didSet{didChange.send() }}
@Published var failedToLogin = false {didSet{didChange.send() }}
@Published var errorMessage = "" {didSet{didChange.send() }}
init () {
handle = Auth.auth().addStateDidChangeListener { (auth, user) in
if let user = user {
self.session = user
self.isLoggedIn = true
//Change isNewUser is user document exists?
} else {
self.session = nil
self.isLoggedIn = false
}
}
}
func logIn(email: String, password: String) {
Auth.auth().signIn(withEmail: email, password: password) { [weak self] user, error in
print("Signed In")
if(error != nil) {
print("Failed to login")
self!.failedToLogin = true
self!.errorMessage = ("\(String(describing: error))")
print(error!)
return
} else if error == nil {
print("Success Logging In")
}
}
}
AppView 根据用户是否登录决定加载哪个视图。
AppView
if !userStore.isLoggedIn {
LoginView().transition(.opacity)
}
if userStore.isLoggedIn {
ContentView().transition(.opacity)
}
未显示 Atm 错误消息;登录视图也在主视图之前不久显示。
如何在视图中正确显示错误消息?
Firebase API 是异步的,因为它们通过互联网访问远程系统,这需要一点时间。顺便说一句,这同样适用于访问本地磁盘。 blog post 对此进行了更详细的解释。
因此,userStore.login
是一个异步过程。 IE。对 if self.userStore.failedToLogin
的调用在 userStore.login
returns 之前执行。因此,userStore.failedToLogin
仍然是false
,条件语句中的代码永远不会执行。
有两种解决方法:
- 在
userStore.logIn
上实现尾随闭包,并将显示错误的代码移至闭包 - 创建
userStore.failedToLogin
发布者并订阅您的快讯的可见性
使用 Combine Firebase:https://github.com/rever-ai/CombineFirebase
这是围绕 firebase api 的 combine-swiftui 包装器,因此您可以对 firebase 使用 swift-ui 发布者模式。