You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift+Firebase登录注册控制:用户验证与登录状态判断咨询

Swift Firebase 身份认证问题修复方案

原代码核心问题

  1. 异步操作导致返回值无效:Firebase的getDocuments是异步执行的,函数会在闭包代码运行前就返回初始值0,闭包内对counter的修改无法同步返回。
  2. 密码存储不安全:直接在Firestore中存储明文密码违反安全规范,应该使用Firebase Auth自带的密码认证机制,避免明文存储风险。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 20:25:22