处理 SwiftUI 组合应用程序中的 Firebase 身份验证错误
Posted
技术标签:
【中文标题】处理 SwiftUI 组合应用程序中的 Firebase 身份验证错误【英文标题】:Handling Firebase Auth error in SwiftUI Combine app 【发布时间】:2020-02-12 22:52:00 【问题描述】:我有一个应用,用户可以在其中使用 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 didSetdidChange.send()
@Published var isNewUser = false didSetdidChange.send()
@Published var failedToCreateAccount = false didSetdidChange.send()
@Published var failedToLogin = false didSetdidChange.send()
@Published var errorMessage = "" didSetdidChange.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 错误信息不显示;登录视图也显示在主视图之前。
如何在视图中正确显示错误消息?
【问题讨论】:
问题似乎是userStore.login
是一个异步过程。 IE。对if self.userStore.failedToLogin
的调用在userStore.login
返回之前执行。因此,userStore.failedToLogin
仍然是false
,条件语句中的代码永远不会被执行。有两种方法可以解决这个问题:1. 在userStore.logIn
上实现一个尾随闭包,并将显示错误的代码移动到闭包中 2. 使userStore.failedToLogin
成为发布者并订阅您的警报的可见性
@PeterFriese 100% 点评论。我会将其发布为答案。 OP - 此行 self.isLoggingIn = true
及其后面的代码将在用户登录之前执行 - 代码比互联网快,您需要从 Firebase 登录闭包中执行下一个“步骤” .请参阅我对this question 的回复以获取更多信息
pod 'CombineFirebase/Auth' 将极大地简化您的问题。除了回调,您可以简单地使用组合发布者模式并使用组合强大的运算符。
【参考方案1】:
Firebase API 是异步的,因为它们通过互联网访问远程系统,这需要一点时间。顺便说一句,这同样适用于访问本地磁盘。这个blog post 更详细地解释了这一点。
因此,userStore.login
是一个异步进程。 IE。对if self.userStore.failedToLogin
的调用在userStore.login
返回之前执行。因此,userStore.failedToLogin
仍然是false
,条件语句中的代码永远不会被执行。
有两种解决方法:
-
在
userStore.logIn
上实现一个尾随闭包,并将显示错误的代码移到闭包中
将userStore.failedToLogin
设为发布者并订阅您的警报的可见性给它
【讨论】:
非常感谢!是的,现在很明显。我还阅读了您关于 Firebase 和 SwiftUI 的 Medium 帖子,Combine;知道 Apple 登录的第 3 部分什么时候出吗?因为这就是我现在正在做的事情.. 感谢@RileyDev 的客气话!在我们说话的同时进行第 3 部分,希望下周能完成! @RileyDev 询问的系列的第 3 部分现已在 peterfriese.dev/replicating-reminder-swiftui-firebase-part3 上提供【参考方案2】:使用合并 Firebase:https://github.com/rever-ai/CombineFirebase
这是对 firebase api 的 combine-swiftui 包装器,因此您可以将 swift-ui 发布者模式用于 firebase。
【讨论】:
以上是关于处理 SwiftUI 组合应用程序中的 Firebase 身份验证错误的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 SwiftUI 中的组合框架从 Spotify API 获取数据