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

SwiftUI中从Firebase Authentication获取用户标识并显示用户名问题

问题

使用SwiftUI开发应用,通过Firebase存储用户数据,登录注册功能正常,但登录后个人资料页因初始username为空无内容显示。登录按钮调用ObservableObject中的signIn()函数,当前函数代码如下:

func signIn(email: String, password: String) {
    auth.signIn(withEmail: email, password: password) { [weak self]
        result, error in
        guard result != nil, error == nil else {
            return
        }
        DispatchQueue.main.async {
            self?.signedIn = true
        }
    }
    if signedIn {
        username = auth.currentUser!.providerID
        
    }
}
解决方案

1. 修复异步逻辑错误

Firebase的signIn(withEmail:password:)是异步方法,你现在把获取用户名的代码写在回调外面,会在登录请求完成前执行,此时signedIn还是初始值false,永远不会进入分支。必须把获取用户名的逻辑移到异步回调内部,且在主线程更新UI相关的@Published变量。

2. 正确获取用户名

auth.currentUser!.providerID是登录提供商ID(比如"password"),不是用户的用户名。正确的用户名来源分两种情况:

  • 如果注册时已经给用户设置了displayName,直接从currentUser?.displayName获取
  • 如果没有设置,需要从Firestore等数据库中读取你存储的用户名

3. 避免强制解包

不要用!强制解包auth.currentUser,改用可选绑定避免空值崩溃。

修正后的代码

func signIn(email: String, password: String) {
    auth.signIn(withEmail: email, password: password) { [weak self] result, error in
        guard let user = result?.user, error == nil else {
            // 这里可以添加错误提示逻辑
            return
        }
        DispatchQueue.main.async {
            self?.signedIn = true
            // 情况1:从displayName获取用户名
            self?.username = user.displayName ?? "匿名用户"
            
            // 情况2:如果用户名存在Firestore,取消下面注释并实现
            /*
            Firestore.firestore().collection("users").document(user.uid).getDocument { docSnapshot, error in
                guard let doc = docSnapshot, doc.exists, let userName = doc.data()?["username"] as? String else {
                    self?.username = "匿名用户"
                    return
                }
                self?.username = userName
            }
            */
        }
    }
}

额外提示

  • 确保username是ObservableObject中的@Published属性,这样SwiftUI才能监听其变化并更新视图
  • 注册用户时,如果需要设置displayName,可以在注册成功后调用:
let changeRequest = user.createProfileChangeRequest()
changeRequest.displayName = "用户名"
changeRequest.commitChanges { error in
    // 处理错误
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 20:22:13