处理SwiftUI Combine应用程序中的Firebase验证错误
我有一个应用程序,用户可以使用Firebase注册和登录。但是,我似乎无法提醒用户视图中的任何错误 首先,我们有一个UserStore,它是一个处理SwiftUI Combine应用程序中的Firebase验证错误,swift,firebase,firebase-authentication,swiftui,combine,Swift,Firebase,Firebase Authentication,Swiftui,Combine,我有一个应用程序,用户可以使用Firebase注册和登录。但是,我似乎无法提醒用户视图中的任何错误 首先,我们有一个UserStore,它是一个observeObject,在SceneDelegate中设置视图时初始化为EnvironmentObject let appView = AppView().environmentObject(userStore) if let windowScene = scene as? UIWindowScene { let window
observeObject
,在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
}
// 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")
}
}
}
然后,实际的方法应该更新UserStore属性值,然后更新视图并显示警报,但情况并非如此
签名
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
}
// 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是异步的,只是因为它们通过internet访问远程系统,这需要一点时间。顺便说一下,访问本地磁盘也是如此。这更详细地解释了这一点 因此,
userStore.login
是一个异步过程。也就是说,如果self.userStore.failedToLogin在userStore.login
返回之前执行调用。因此,userStore.failedToLogin
仍然是false
,条件语句中的代码将永远不会执行
有两种解决方法:
在userStore.logIn
上实现后续闭包,并将显示错误的代码移到闭包中
将userStore.failedToLogin
设为发布者,并向其订阅警报的可见性
Firebase API是异步的,只是因为它们通过internet访问远程系统,这需要一点时间。顺便说一下,访问本地磁盘也是如此。这更详细地解释了这一点
因此,userStore.login
是一个异步过程。也就是说,如果self.userStore.failedToLogin
在userStore.login
返回之前执行调用。因此,userStore.failedToLogin
仍然是false
,条件语句中的代码将永远不会执行
有两种解决方法:
在userStore.logIn
上实现后续闭包,并将显示错误的代码移到闭包中
将userStore.failedToLogin
设为发布者,并向其订阅警报的可见性
使用Combine Firebase:
这是围绕firebase api的组合swiftui包装,所以您可以为firebase使用swift ui发布者模式 使用联合火力基地:
这是围绕firebase api的组合swiftui包装,所以您可以为firebase使用swift ui发布者模式 问题似乎在于userStore.login
是一个异步过程。也就是说,如果self.userStore.failedToLogin
在userStore.login
返回之前执行调用。因此,userStore.failedToLogin
仍然是false
,条件语句中的代码将永远不会执行。有两种方法可以解决这个问题:1。在userStore.logIn
上实现一个尾随闭包,并将显示错误的代码移到闭包2中。将userStore.failedToLogin
设为发布者,并将警报的可见性订阅给it@PeterFriese100%的点评。我会把这作为一个答案。OP-这一行self.isLoggingIn=true
和它后面的代码将在用户登录之前执行-代码比互联网快,您需要在Firebase登录关闭内执行下一个“步骤”。请参阅我对的回答,以获取更多信息。POD“CombineFreebase/Auth”将极大地简化您的问题。您可以简单地使用联合发布模式和联合功能强大的运算符,而不是回调。问题似乎在于userStore.login
是一个异步过程。也就是说,如果self.userStore.failedToLogin
在userStore.login
返回之前执行调用。因此,userStore.failedToLogin
仍然是false
,条件语句中的代码将永远不会执行。有两种方法可以解决这个问题:1。在userStore.logIn
上实现一个尾随闭包,并将显示错误的代码移到闭包2中。将userStore.failedToLogin
设为发布者,并将警报的可见性订阅给it@PeterFriese100%的点评。我会把这作为一个答案。OP-这一行self.isLoggingIn=true
和它后面的代码将在用户登录之前执行-代码比互联网快,您需要在Firebase登录关闭内执行下一个“步骤”。请参阅我对的回答,以获取更多信息。POD“CombineFreebase/Auth”将极大地简化您的问题。不用回调,您只需使用联合发布模式和强大的联合操作符即可。非常感谢!是的,现在很明显了。我也读了你关于Firebase和SwiftUI的中篇文章,Combine;你知道苹果登录的第三部分什么时候发布吗?因为这就是我现在正在做的……谢谢你的好话,@Riledev!我们正在讨论第三部分,希望下周能发布!@RileyDev Asquired about系列的第3部分现在可以在Thank you soo Money上找到!是的,现在很明显了。我也读了你关于Firebase和SwiftUI的中篇文章,Combine;你知道苹果登录的第三部分什么时候发布吗?因为这就是我现在正在做的……谢谢你的好话,@Riledev!我们正在讨论第三部分,希望下周能发布!@RileyDev提问系列的第3部分现已在