Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理SwiftUI Combine应用程序中的Firebase验证错误_Swift_Firebase_Firebase Authentication_Swiftui_Combine - Fatal编程技术网

处理SwiftUI Combine应用程序中的Firebase验证错误

处理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

我有一个应用程序,用户可以使用Firebase注册和登录。但是,我似乎无法提醒用户视图中的任何错误

首先,我们有一个UserStore,它是一个
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部分现已在