Swift+Firebase登录注册控制:用户验证与登录状态判断咨询
Swift Firebase 身份认证问题修复方案
原代码核心问题
- 异步操作导致返回值无效:Firebase的
getDocuments是异步执行的,函数会在闭包代码运行前就返回初始值0,闭包内对counter的修改无法同步返回。 - 密码存储不安全:直接在Firestore中存储明文密码违反安全规范,应该使用Firebase Auth自带的密码认证机制,避免明文存储风险。
getUser函数逻辑错误:调用document(username)后无需再添加whereField条件,且单个文档查询应使用getDocument而非getDocuments。
正确实现方案
1. 检查用户是否已登录
直接使用Firebase Auth的currentUser属性即可快速判断,无需查询Firestore:
import FirebaseAuth func isUserLoggedIn() -> Bool { return Auth.auth().currentUser != nil }
2. 验证用户名和密码(推荐使用Firebase Auth原生方法)
Firebase Auth提供了完整的用户名/密码认证流程,无需自己在Firestore中管理用户密码:
import FirebaseAuth // 异步回调版本 func signIn(withUsername email: String, password: String, completion: @escaping (Bool, Error?) -> Void) { Auth.auth().signIn(withEmail: email, password: password) { authResult, error in if let error = error { completion(false, error) return } completion(true, nil) } } // Swift 5.5+ async/await版本(更简洁) func signIn(withUsername email: String, password: String) async throws -> Bool { let authResult = try await Auth.auth().signIn(withEmail: email, password: password) return authResult.user != nil }
3. 若需自定义用户存储(配合Firebase Auth)
如果需要在Firestore中存储额外用户信息,可在用户注册时将UID与用户信息关联,验证时先通过Firebase Auth登录,再查询Firestore:
import FirebaseAuth import FirebaseFirestore // 验证用户名密码并获取用户信息(async/await版本) func validateUserAndGetInfo(username: String, password: String) async throws -> [String: Any]? { // 先通过Firebase Auth验证密码 let authResult = try await Auth.auth().signIn(withEmail: username, password: password) let userId = authResult.user.uid // 从Firestore获取用户信息 let documentSnapshot = try await Firestore.firestore().collection("users").document(userId).getDocument() return documentSnapshot.data() }
原getUser函数的修正(仅用于查询用户是否存在,不验证密码)
import FirebaseFirestore // 异步回调版本 func checkUserExists(username: String, completion: @escaping (Bool) -> Void) { Firestore.firestore().collection("users").whereField("username", isEqualTo: username).getDocuments { snapshot, error in guard let snapshot = snapshot, error == nil else { completion(false) return } completion(!snapshot.documents.isEmpty) } } // async/await版本 func checkUserExists(username: String) async throws -> Bool { let snapshot = try await Firestore.firestore().collection("users").whereField("username", isEqualTo: username).getDocuments() return !snapshot.documents.isEmpty }
关键注意事项
- 永远不要存储明文密码:Firebase Auth会自动处理密码的哈希存储与验证,避免密码泄露风险。
- 优先使用异步回调或async/await:Firebase的所有网络请求都是异步的,同步返回值无法获取正确结果。
- 使用Firebase Auth的
currentUser判断登录状态:这是官方推荐的方式,比自己查询Firestore更高效可靠。
内容的提问来源于stack exchange,提问作者Andrea Scorza
相关产品推荐
相关产品推荐

