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
相关产品推荐
相关产品推荐

