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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:58:12