如何在SwiftUI中使用Firebase Auth登录后检查用户是否已经存在于Firestore集合中


@Published var isNewUser: Bool?
init() {
self.isNewUser = false
}
func checkIfTheUserExistsInDataBase(
userID: String?, completion: @escaping (_ isNewuser: Bool) -> Void
) {
let docRef = db.collection("users").whereField("user_id", isEqualTo: userID!).limit(to: 1)
docRef.getDocuments { querySnapshot, error in
if error != nil {
print(error?.localizedDescription)
} else {
if let doc = querySnapshot?.documents, doc.isEmpty {
completion(true)
} else {
completion(false)
}
}
}
}
func login(
email: String, password: String,
completion: @escaping (_ error: Error?, _ isEmailVerified: Bool) -> Void
) {
Auth.auth().signIn(withEmail: email, password: password) { authDataResult, error in
if error == nil {
if authDataResult!.user.isEmailVerified {
DispatchQueue.main.async {
self.checkIfTheUserExistsInDataBase(userID: authDataResult?.user.uid) { isNewUser in
self.isNewUser = isNewUser
}
}
UserDefaults.standard.set(authDataResult?.user.uid, forKey: CurrentUserDefaults.userID)
completion(error, true)
} else {
print("Email not verified")
completion(error, false)
}
} else {
completion(error, false)
}
}
}

我试图使用DispatchSemaphore让一个更长的运行函数首先执行,这是checkIfTheUserExistsInDataBase,但它冻结了我的应用程序。有没有更好的方法来做到这一点?

Firebase支持async/await(请参阅我创建的这段简短视频和这篇博客文章,详细解释这一点)。

回答你的问题:你应该使用async/await来呼叫签入用户,等待结果,检查用户是否存在于你的Firestore集合中,并更新UI。

下面的代码片段(基于这个示例应用程序)使用Firestore中的新COUNT特性来计算users集合中的文档数量,以确定是否至少有一个用户具有刚刚登录的用户的ID。

func isNewUser(_ user: User) async -> Bool {
let userId = user.uid
let db = Firestore.firestore()
let collection = db.collection("users")
let query = collection.whereField("userId", isEqualTo: userId)
let countQuery = query.count
do {
let snapshot = try await countQuery.getAggregation(source: .server)
return snapshot.count.intValue >= 0
}
catch {
print(error)
return false
}
}
func signInWithEmailPassword() async -> Bool {
authenticationState = .authenticating
do {
let authResult = try await Auth.auth().signIn(withEmail: self.email, password: self.password)
if await isNewUser(authResult.user) {
}
return true
}
catch  {
print(error)
errorMessage = error.localizedDescription
authenticationState = .unauthenticated
return false
}
}

有关如何在SwiftUI应用程序中实现Firebase身份验证的更多细节,请参阅此视频。

最新更新