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

SwiftUI集成Firebase Apple登录触发无效状态致命错误求助

Apple登录集成Firebase时currentNonce丢失导致崩溃的排查方案

核心问题分析

崩溃触发点在handleSignInWithAppleCompletion中currentNonce为nil的断言,本质是登录请求阶段生成的nonce在回调时丢失,常见原因是实例生命周期不稳定或内存被系统回收。

排查与修复步骤

1. 确保SignInManager实例的生命周期稳定性

如果在SwiftUI中把SignInManager错误声明为@State或放在View的临时作用域内,View刷新时会重新初始化实例,直接清空currentNonce。

  • 正确实现方式:用全局单例或@StateObject持有实例(iOS14+适用):
// 全局单例模式
final class SignInManager: ObservableObject {
    static let shared = SignInManager()
    private init() {} // 私有初始化保证唯一实例
    
    // ... 原有代码
}

// SwiftUI View中使用
struct LoginView: View {
    @StateObject private var signInManager = SignInManager.shared
    // ...
}

2. 持久化currentNonce避免内存回收丢失

用户切换APP完成Apple授权后,后台APP可能被系统回收内存,导致currentNonce被释放。临时将nonce存入UserDefaults做兜底:

extension SignInManager {
    func handleSignInWithAppleRequest(_ request: ASAuthorizationAppleIDRequest) {
        request.requestedScopes = [.fullName, .email]
        let nonce = randomNonceString()
        currentNonce = nonce
        // 存入UserDefaults做备份
        UserDefaults.standard.set(nonce, forKey: "AppleSignInNonce")
        request.nonce = sha256(nonce)
    }
    
    func handleSignInWithAppleCompletion(_ result: Result<ASAuthorization, Error>) {
        if case .failure(let failure) = result {
            errorMessage = failure.localizedDescription
            // 失败时清除备份的nonce
            UserDefaults.standard.removeObject(forKey: "AppleSignInNonce")
        }
        else if case .success(let success) = result {
            if let appleIDCredential = success.credential as? ASAuthorizationAppleIDCredential {
                // 优先取内存中的nonce,内存无则取备份
                guard let nonce = currentNonce ?? UserDefaults.standard.string(forKey: "AppleSignInNonce") else {
                    fatalError("Invalid state: a login callback was received, but no login request was sent.")
                }
                // 使用后清除备份
                UserDefaults.standard.removeObject(forKey: "AppleSignInNonce")
                
                // ... 原有后续认证代码
            }
        }
    }
}

3. 验证nonce生成与传递的一致性

  • 检查sha256方法输出:Firebase要求哈希值为小写十六进制字符串,当前代码的%02x格式符合要求,无需修改。
  • 在handleSignInWithAppleRequest中打印currentNonce和request.nonce,确认两者关联正确,且未被其他代码意外篡改。

4. 核对Firebase与Apple开发者配置

  • 确认Apple开发者后台的Sign In with Apple配置、Firebase控制台的Apple登录配置(Team ID、Bundle ID、重定向URI)完全匹配。
  • 确保Apple登录回调直接传递给SignInManager的handleSignInWithAppleCompletion,无中间层导致状态丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 07:25:17