iOS + Amplify 如何获取Cognito当前登录用户的唯一标识符
问题原因说明
Amplify.Auth.getCurrentUser()返回的userId是Cognito为用户全局生成的唯一sub标识符,和你业务侧用邮箱作为唯一标识的逻辑是两套体系,所以拿不到邮箱属于预期行为。- 你无法直接用
attributes.email取值的原因是fetchUserAttributes返回的[AuthUserAttribute]是数组类型,每个元素携带key和value字段,没有直接封装成带email属性的结构体,所以需要按key匹配取值。 - 你当前写的
fetchAttributes方法存在严重的异步逻辑问题:Amplify.Auth.fetchUserAttributes是异步方法,回调执行时机晚于函数return,你拿到的userId永远为空字符串,无法正常返回结果。
正确简洁的实现方案
你可以用高阶函数快速过滤出邮箱属性,同时修正异步返回逻辑,避免同步返回的问题。另外系统已经内置了AuthUserAttributeKey.email枚举,不需要手动对比rawValue,避免拼写错误。
回调版本写法
func fetchUserEmail(completion: @escaping (String?, Error?) -> Void) { Amplify.Auth.fetchUserAttributes() { result in switch result { case .success(let attributes): // 直接用first(where:)过滤email属性,无需手动遍历 let email = attributes.first { $0.key == .email }?.value completion(email, nil) case .failure(let error): completion(nil, error) } } }
调用示例:
fetchUserEmail { email, error in if let error = error { print("获取用户属性失败: \(error)") return } guard let email = email else { print("用户未绑定邮箱") return } // 拿到邮箱后执行业务逻辑,比如查询Dynamo数据 print("当前用户唯一标识邮箱: \(email)") }
Swift 5.5+ Async/Await 版本写法(更简洁)
如果你的项目支持Swift Concurrency,可以直接用异步函数写法,避免回调嵌套:
func fetchUserEmail() async throws -> String? { let attributes = try await Amplify.Auth.fetchUserAttributes() return attributes.first { $0.key == .email }?.value }
调用示例:
Task { do { guard let email = try await fetchUserEmail() else { print("用户未绑定邮箱") return } // 执行业务逻辑 print("当前用户邮箱: \(email)") } catch { print("获取用户属性失败: \(error)") } }
内容的提问来源于stack exchange,提问作者Arturo
相关产品推荐
相关产品推荐

