iOS Firebase更新邮箱时无法捕获userTokenExpired错误,求排查
为什么Firebase Auth更新邮箱时userTokenExpired分支从未触发?
我尝试手动检查用户是否需要重新认证,为此编写了以下代码来处理邮箱更新:
//MARK: updateEmail static func updateEmail(email: String, finished: @escaping (_ done: Bool, _ hasToReauthenticate: Bool) -> Void) { let currentUser = Auth.auth().currentUser currentUser?.updateEmail(to: email) { err in if err != nil { if let errCode = AuthErrorCode(rawValue: err!._code) { switch errCode { case .userTokenExpired: print("expired") finished(true, true) break default: Utilities.showErrorPopUp(labelContent: "Fehler", description: err!.localizedDescription) finished(false, false) } } } else { finished(true, false) } } }
但即便在应该触发.userTokenExpired分支的场景下,代码也从未进入该分支,请问我遗漏了什么?
问题根源:你监听错了错误码!
Firebase Auth 对修改邮箱、密码这类敏感操作有专门的安全限制:哪怕用户的Token还没过期,只要用户不是在"最近一段时间内登录"的(通常是几小时内),执行这类操作时返回的错误码是.userRequiresRecentLogin,而非.userTokenExpired。
.userTokenExpired只会在用户的ID Token真正过期(比如超过默认1小时有效期)且未自动刷新的场景下触发——这种情况更多出现在长时间未操作的后台请求里,和敏感操作的重新认证需求完全是两回事。
修正方案
调整你的错误处理分支,加入.userRequiresRecentLogin的判断,同时保留.userTokenExpired的处理以覆盖真正的Token过期场景:
//MARK: updateEmail static func updateEmail(email: String, finished: @escaping (_ done: Bool, _ hasToReauthenticate: Bool) -> Void) { let currentUser = Auth.auth().currentUser currentUser?.updateEmail(to: email) { err in if err != nil { if let errCode = AuthErrorCode(rawValue: err!._code) { switch errCode { case .userTokenExpired, .userRequiresRecentLogin: // 两种场景都需要引导用户重新认证 print("需要重新认证") finished(true, true) default: Utilities.showErrorPopUp(labelContent: "Fehler", description: err!.localizedDescription) finished(false, false) } } } else { finished(true, false) } } }
额外提示
当触发重新认证需求时,你需要调用currentUser?.reauthenticate(with: credential)方法,让用户重新输入密码(或通过其他登录方式验证身份),验证成功后再重新执行更新邮箱的操作。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

