Swift使用Firebase Auth登录时输入正确凭证始终返回false如何解决?
问题根因
核心问题是异步逻辑处理错误,和Firebase Auth服务端无关,你看到的控制台日志属于Firebase SDK的常规输出,其中请求返回的error字段为null,已经说明登录请求本身执行成功。
具体原因如下:
- Firebase的
signIn(withEmail:password:)和addStateDidChangeListener都是异步回调方法,不会阻塞当前线程执行,你当前用同步返回值的方式接收异步结果,逻辑完全不成立。 signInToApp方法执行时,会先给signInSuccess赋值为false,之后触发的登录网络请求是后台执行的,方法不会等待请求回调就直接走到return语句返回false。哪怕后续回调中把signInSuccess修改为true,也不会改变已经返回的结果,所以你会先收到false触发错误弹窗。- 后续可以正常进入下一页,是因为你注册的Auth状态监听器在登录请求完成后收到了状态变更通知,更新了全局的
signedIn状态,界面响应状态变化完成了跳转,和登录方法的返回值无关。 - 额外注意:你当前的
isUserSignedIn方法存在逻辑错误,每次调用都会注册一个新的状态监听器,多次调用会重复注册导致内存泄漏,这个方法本身没有必要,单次判断登录状态直接用Auth.auth().currentUser != nil即可,状态监听器只需要在全局初始化时注册一次用来响应登录状态变更即可。
修复方案
方案1:改造为闭包回调模式(兼容所有iOS版本)
将同步返回改为通过逃逸闭包传递异步结果:
// 改造后的登录方法 func signInToApp(email: String, password: String, completion: @escaping (Bool, Error?) -> Void) { // 直接用currentUser判断当前登录状态,不需要调用isUserSignedIn if Auth.auth().currentUser != nil { completion(true, nil) return } Auth.auth().signIn(withEmail: email, password: password) { result, error in if let error = error { print(error.localizedDescription) completion(false, error) } else { completion(true, nil) } } }
调用时在闭包内处理结果,UI相关操作需要切换到主线程执行:
signInToApp(email: 用户输入的邮箱, password: 用户输入的密码) { success, error in DispatchQueue.main.async { if success { // 登录成功逻辑,跳转到下一页 } else { // 登录失败,弹出错误提示 } } }
方案2:使用async/await(适配iOS 15及以上版本)
语法更简洁,不需要处理闭包嵌套:
func signInToApp(email: String, password: String) async throws -> Bool { if Auth.auth().currentUser != nil { return true } try await Auth.auth().signIn(withEmail: email, password: password) return true }
调用方式:
Task { do { let loginSuccess = try await signInToApp(email: 用户输入的邮箱, password: 用户输入的密码) await MainActor.run { // 登录成功逻辑 } } catch { await MainActor.run { // 弹出错误提示 } } }
内容的提问来源于stack exchange,提问作者8bitwonder
相关产品推荐
相关产品推荐

