如何从 Firestore 加载用户数据并在 Swift 中异步验证后更新我的视图?

问题描述 投票:0回答:1

我正在寻找一种方法,在身份验证完成后从 Firestore 数据库获取用户,并获取用户的 UID,但在 SwiftUI/Swift 5+ 上加载视图之前。或者,我可以在两者之间添加一个 ProgressView。

在我的 ContentView 视图中,我有一个关于用户是否已加入的条件子句。这是我需要访问的 Firebase 用户文档中的一个字段。

我遇到的问题是,当我的视图加载时,当我需要数据库中的值时,它会加载我的 User 结构的默认值。

这是我现在的解决方案:

我创建了一个 SessionStore 类来处理 Firebase 的登录:

class SessionStore : ObservableObject {
  u/Published var session: SessionUser? { didset { self.didChange.send(self) } }
  var handle: AuthStateDidChangeListenerHandle?

  // Auth listening by running addStateDidChangeListener
  func listen() { ... }

  // Unbind the Auth listener
  func unbind() { ... }

  func handleGoogleLogin() {
    GIDSignIn.sharedInstance.signIn(withPresenting: getRootViewController()) {
              signInResult, err in
    ...
    
      signInResult.user.refreshTokensIfNeeded { user, error in
      ...

        Auth.auth().signIn(with: credential) { result, err in
          print("success!")
          // TODO: run fetch user here somehow
        }
      }
    }
  }
}

然后在我的 SessionUser 对象中,我可以调用从 Firestore 上的集合中获取数据:

class SessionUser : ObservableObject {
  @Published var user: User?
  @Published var isUserOnboarded: Bool
  var uid: String
  
  init(uid) { ... }

  func fetchSessionUser() async {
    do {
      // Tries to get user from the datastore first in case user exists already
      if doesUserExist() {
        // Get user from Firestore db
        let doc = try await db.collection("users").document("\(userId)")
        if doc.exists {
          self.user = try document.data(as: User.self)
          self.isUserOnboarded = self.user.isUserOnboarded
        }
      } else {
        // Create user
      }
    }
  }
}

对于后代,这是 ContentView 视图:

struct ContentView: View {
  @StateObject var session: SessionStore = SessionStore()

  var body: some View {
    VStack {
      if session.session != nil || Auth.auth().currentUser != nil {
        if session.session?.isUserOnboarded {
          MainView()
        } else {
          OnboardingView()
        }
      } else {
        StartPageView()
      }
   }
}

我已经尝试了很多事情,例如在 fetch 调用中转义对象,使用 isUserOnboarded 的已发布变量创建封装类(如上所示),以及使用 DispatchQueue.main.async 调用,但没有任何效果到目前为止已经工作了。

StackOverflow/online 上的先前答案显示 Firebase 的 Auth 过程是异步的(但我猜它不再是异步的),并且它不允许我用等待调用它。

swift firebase google-cloud-platform google-cloud-firestore firebase-authentication
1个回答
0
投票

我正在寻找一种在身份验证完成后从我的 Firestore 数据库获取用户的方法。

确实,当身份验证过程成功时,您可以获取 Fireabsae 用户对象,然后在代码中进一步使用它,但这并不能解决整个问题,只能解决一半。那么用户退出怎么办?

因此,如果您想跟踪用户身份验证状态并采取相应的操作,那么我建议您使用身份验证状态侦听器。通过这种方式,您将能够跟踪不同组件或整个应用程序的身份验证状态。

© www.soinside.com 2019 - 2024. All rights reserved.