【问题标题】:Firebase session variable is always nilFirebase 会话变量始终为零
【发布时间】:2021-02-27 02:17:38
【问题描述】:

应用程序架构很简单:如果会话变量为零,则会出现登录屏幕。如果成功输入密码和登录名,我们将创建一个新的用户模型,并且会话变量不再为 nil。但是,这并没有发生,因此无论登录是否成功,登录屏幕总是出现在我们面前。

(我在打开应用程序“Got user: ”时收到一条调试消息,表明身份验证没有问题)

ContentView.swift:

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var session: SessionStore
    
    func getUser () {
          session.listen()
      }

    var body: some View {
        Group {
            if (session.session != nil) {
                Text("Hello user!")
              } else {
                SignInView()
              }
        }.onAppear(perform: getUser)
    }
}

SessionStore.swift:

import SwiftUI
import Firebase
import Combine

class SessionStore : ObservableObject {
    var didChange = PassthroughSubject<SessionStore, Never>()
    var session: User? { didSet { self.didChange.send(self) }}
    var handle: AuthStateDidChangeListenerHandle?

    func listen () {
        // monitor authentication changes using firebase
        handle = Auth.auth().addStateDidChangeListener { (auth, user) in
            if let user = user {
                // if we have a user, create a new user model
                print("Got user: \(user)")
                self.session = User(
                    uid: user.uid,
                    displayName: user.displayName,
                    email: user.email
                    
                )
            } else {
                // if we don't have a user, set our session to nil
                self.session = nil
            }
        }
    }

    func signUp(
            email: String,
            password: String,
            handler: @escaping AuthDataResultCallback
            ) {
            Auth.auth().createUser(withEmail: email, password: password, completion: handler)
        }

    func signIn(
        email: String,
        password: String,
        handler: @escaping AuthDataResultCallback
        ) {
        Auth.auth().signIn(withEmail: email, password: password, completion: handler)
    }

    func signOut () -> Bool {
        do {
            try Auth.auth().signOut()
            self.session = nil
            return true
        } catch {
            return false
        }
    }
}

SignInView.swift:

import SwiftUI

struct SignInView : View {

    @State var email: String = ""
    @State var password: String = ""
    @State var loading = false
    @State var error = false

    @EnvironmentObject var session: SessionStore

    func signIn () {
        loading = true
        error = false
        session.signIn(email: email, password: password) { (result, error) in
            self.loading = false
            if error != nil {
                self.error = true
            } else {
                self.email = ""
                self.password = ""
            }
        }
    }

    var body: some View {
        VStack {
            TextField("email address", text: $email)
            SecureField("password", text: $password)
            if (error) {
                Text("ahhh crap")
            }
            Button(action: signIn) {
                Text("Sign In")
            }
        }
    }
}

【问题讨论】:

    标签: ios swift firebase firebase-authentication swiftui


    【解决方案1】:

    要让视图观察到属性,您需要将其发布,而不是使用自定义发布者,例如

    class SessionStore : ObservableObject {
        @Published var session: User? = nil    // << here !!
    
    // ... other code
    

    最好在主队列上明确分配已发布的属性,例如

     DispatchQueue.main.async {
        self.session = User(
            uid: user.uid,
            displayName: user.displayName,
            email: user.email
        )
     }
    

    【讨论】:

      猜你喜欢
      • 2021-11-28
      • 1970-01-01
      • 1970-01-01
      • 2021-10-24
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多