我对 iOS 编程尤其是 swiftUI 还很陌生。 我有一个问题,我试图在我的应用程序中集成 firebase auth 以管理用户。 现在登录和注销基本上可以正常工作了,问题是,登录后,我的 View (有条件地呈现 Google 登录按钮或内容列表不会重新呈现,所以我仍然看到登录按钮,甚至尽管我已登录)。
我已经设置了一个可观察对象来保存我的身份验证状态,但不幸的是,它不会自动重新加载当前用户。所以我设置了一个函数来手动重新加载它,我想在登录时触发它。这适用于注销按钮,但登录在 AppDelegate 中完成,由于某种原因我无法访问 reloadUser() 函数。
我相信有更好的方法可以做到这一点,如果有任何帮助,我将不胜感激!
环境:
final class UserData: ObservableObject {
@Published var showFavoritesOnly = false
@Published var qrTags = qrTagData
@Published var user: User? = Auth.auth().currentUser
func reloadUser() -> Void {
self.user = Auth.auth().currentUser
}
}
我要渲染的 View :
struct MyQuaggsList: View {
@EnvironmentObject private var userData: UserData
var body: some View {
Group {
if getLogInState() != nil {
VStack {
NavigationView {
List {
Toggle(isOn: $userData.showFavoritesOnly) {
Text("Show Favorites Only")
}
ForEach(userData.qrTags) { qrTag in
if !self.userData.showFavoritesOnly || qrTag.isFavorite {
NavigationLink(
destination: QuagDetail(qrTag: qrTag)
.environmentObject(self.userData)
) {
QuaggRow(qrTag: qrTag)
}
}
}
}
.navigationBarTitle(Text("My Quaggs"))
}
SignOutButton()
}
} else {
SignInView()
}
}.onAppear(perform: {self.userData.reloadUser()})
}
func getLogInState() -> User? {
return Auth.auth().currentUser
}
}
另外,请注意 .onAppear() 函数,不幸的是,该函数仅在初始出现时触发,而不是在用户登录后重新出现 View 时触发。
提前致谢!这真的很令人沮丧。
最佳答案
firebase 和 swiftUI 组合起初有点棘手,但您会发现每个项目都使用相同的模式,不用担心。 只需按照我的步骤定制您的项目,这是我们的策略。
- 这可能是一个很长的答案,但我想将其作为所有在 Stack OverFlow 中管理的 Firebase-SwiftUI 用户的引用。 -
- 创建一个提供 BindableObject 的 SessionStore 类,并听取您的用户身份验证并处理 Auth 和 CRUD 方法。
- 为我们的项目创建模型(您已经这样做了)
- 在 SessionStore 类中添加 Auth 方法。
- 倾听变化并将事物整合在一起。
让我们从 SessionStore 类开始: 导入 SwiftUI 导入 Firebase 导入组合
class SessionStore : BindableObject {
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
)
} else {
// if we don't have a user, set our session to nil
self.session = nil
}
}
}
// additional methods (sign up, sign in) will go here
}
请注意,我们已经声明我们的 session 属性是一个可选的 User 类型,我们还没有定义它。让我们快速制作一个:
class User {
var uid: String
var email: String?
var displayName: String?
init(uid: String, displayName: String?, email: String?) {
self.uid = uid
self.email = email
self.displayName = displayName
}
}
现在,添加signUp、signIn 和signOut/strong>方法
class SessionStore : BindableObject {
// prev code...
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
}
}
}
最后,我们需要一种方法来停止监听我们的身份验证更改处理程序。
class SessionStore : BindableObject {
// prev code...
func unbind () {
if let handle = handle {
Auth.auth().removeStateDidChangeListener(handle)
}
}
}
最后,制作我们的内容 View :
import SwiftUI
struct ContentView : View {
@EnvironmentObject var session: SessionStore
var body: some View {
Group {
if (session.session != nil) {
Text("Hello user!")
} else {
Text("Our authentication screen goes here...")
}
}
}
}
关于ios - 用户在 Firebase 上使用 Google 登录后,如何在 swiftUI 中重新呈现我的 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62083056/