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

SwiftUI中Firebase认证与Firestore用户管理实现咨询

解决Firebase注册自动创建用户文档与登录获取CustomUser的问题

1. 用户注册时自动在“users”集合创建用户文档

你的SignUpwithEmailAndPassword函数目前仅完成Firebase Auth账户创建,未同步数据到Firestore的users集合。需要在注册成功后,基于Auth返回的用户信息生成CustomUser实例并写入Firestore。

步骤1:修正userDataManagment的addUser函数

原函数存在逻辑错误(依赖未初始化的self.sessionUser),修改为接收Firebase Auth的User对象,生成对应CustomUser并写入:

func addUser(from authUser: User) {
    // 根据Auth用户信息创建CustomUser实例,按需补充自定义字段
    let customUser = CustomUser(
        id: authUser.uid,
        email: authUser.email ?? "",
        displayName: authUser.displayName ?? ""
    )
    
    let docRef = db.collection("users").document(authUser.uid)
    do {
        try docRef.setData(from: customUser)
        print("用户文档创建成功")
        self.sessionUser = customUser // 可选:同步到当前会话用户
    } catch {
        print("创建用户文档失败:\(error.localizedDescription)")
    }
}

注:确保CustomUser结构体实现Codable,并通过@DocumentID标记id字段,适配Firestore编码要求

步骤2:修改authenticationViewModel的注册函数

在注册成功后调用userDataManagment的addUser方法,完成Firestore文档创建:

func SignUpwithEmailAndPassword(userDataManager: UserDataManagment) async -> Bool {
    authenticationState = .Authenticating
    do {
        let authResult = try await Auth.auth().createUser(withEmail: email, password: password)
        print("用户 \(authResult.user.uid) 注册成功")
        
        // 同步创建Firestore用户文档
        userDataManager.addUser(from: authResult.user)
        
    } catch {
        print(error)
        errorMessage = error.localizedDescription
        authenticationState = .UnAuthenticated
        return false
    }
    authenticationState = .Authenticated
    errorMessage = ""
    return true
}

调用注册函数时,需传入UserDataManagment实例,或在authenticationViewModel中持有其引用

2. 用户登录后获取对应的CustomUser结构体

登录成功后,需触发userDataManagment加载当前用户的Firestore文档数据到sessionUser。

步骤1:修改authenticationViewModel的登录函数

在登录成功后调用userDataManagment的getUserData方法:

func SignInWithEmailAndPassword(userDataManager: UserDataManagment) async -> Bool {
    authenticationState = .Authenticating
    do {
        let authResult = try await Auth.auth().signIn(withEmail: email, password: password)
        print("用户 \(authResult.user.uid) 登录成功")
        
        // 加载用户Firestore数据
        userDataManager.getUserData(documentID: authResult.user.uid)
        
    } catch {
        print(error)
        errorMessage = error.localizedDescription
        authenticationState = .UnAuthenticated
        return false
    }
    authenticationState = .Authenticated
    errorMessage = ""
    return true
}

步骤2:优化userDataManagment的初始化逻辑

原init中直接调用getUserData可能在Auth用户未就绪时触发错误,可改为监听Auth状态变化,自动加载数据:

init() {
    // 监听Auth状态变化,登录/注册后自动加载用户数据
    Auth.auth().addStateDidChangeListener { [weak self] auth, user in
        guard let self = self, let userId = user?.uid else {
            self?.sessionUser = nil
            return
        }
        self.getUserData(documentID: userId)
    }
}

这样无论用户是手动登录、注册还是自动登录,都会自动同步CustomUser数据。

额外修正点

  • userDataManagment的updateUserData函数存在集合名称错误,需修正:
    func updateUserData(user: CustomUser) {
        if let id = user.id {
            let docRef = db.collection("users").document(id) // 修正为"users"集合
            do {
                try docRef.setData(from: user)
            } catch {
                print("更新用户数据失败:\(error.localizedDescription)")
            }
        }
    }
    
  • CustomUser结构体示例(确保适配Firestore):
    struct CustomUser: Codable, Identifiable {
        @DocumentID var id: String?
        var email: String
        var displayName: String
        // 按需添加其他自定义字段
    }
    

内容的提问来源于stack exchange,提问作者EdG

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 21:01:36