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

如何基于PhoneVerificationController实现Firebase多因素SMS认证

问题描述

我正在使用PhoneVerificationController包,想要实现Firebase的多因素SMS认证功能,但不知如何修改代码。修改后出现「Missing argument for parameter 'signIn' in call」报错,恳请指导修改方向。

原代码

@IBAction func startVerification() {
    let configuration = Configuration(requestCode: { phone, completion in
        PhoneAuthProvider.provider().verifyPhoneNumber(phone, uiDelegate: nil, completion: completion)
    }, signIn: { verificationID, verificationCode, completion in
        let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID, verificationCode: verificationCode)
        Auth.auth().signIn(with: credential) { _, error in completion(error) }
    })
    let vc = PhoneVerificationController(configuration: configuration)
    vc.delegate = self
    present(vc, animated: true)
}

Firebase官方示例代码

let user = Auth.auth().currentUser
user?.multiFactor.getSessionWithCompletion({ (session, error) in
    // Send SMS verification code.
    PhoneAuthProvider.provider().verifyPhoneNumber(
        phoneNumber,
        uiDelegate: nil,
        multiFactorSession: session) { (verificationId, error) in
            // verificationId will be needed for enrollment completion.
            // Ask user for the verification code.
            let credential = PhoneAuthProvider.provider().credential(
                withVerificationID: verificationId!,
                verificationCode: kPhoneSecondFactorVerificationCode)
            let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
            // Complete enrollment. This will update the underlying tokens
            // and trigger ID token change listener.
            user.multiFactor.enroll(with: assertion, displayName: displayName) { (error) in
                // ...
            }
    }
})

我的修改代码

let user = Auth.auth().currentUser
user?.multiFactor.getSessionWithCompletion({ (session, error) in
    let configuration = Configuration(requestCode: { phone, completion in
        PhoneAuthProvider.provider().verifyPhoneNumber(phone, uiDelegate: nil, multiFactorSession: session) { (verificationId, error) in
            let credential = PhoneAuthProvider.provider().credential(
                withVerificationID: verificationId!,
                verificationCode: kPhoneSecondFactorVerificationCode)
            let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
            // Complete enrollment. This will update the underlying tokens
            // and trigger ID token change listener.
            user.multiFactor.enroll(with: assertion, displayName: displayName) { (error) in
            }
        }
    })
    let vc = PhoneVerificationController(configuration: configuration)
    vc.delegate = self
    present(vc, animated: true)
}

解决方案

报错原因

「Missing argument for parameter 'signIn' in call」错误是因为Configuration初始化必须同时传入requestCode和signIn两个闭包参数,你的修改代码只传了requestCode,缺少signIn参数导致的。

正确修改方向

PhoneVerificationController的设计是把「请求验证码」和「验证验证码并完成认证」拆分成两个闭包,对应多因素认证的流程,你需要把Firebase多因素的逻辑拆分到这两个闭包里:

  1. requestCode闭包:负责基于多因素会话发送验证码
  2. signIn闭包:负责用验证码生成多因素断言,完成注册

修改后的代码示例:

@IBAction func startVerification() {
    guard let user = Auth.auth().currentUser else {
        // 处理用户未登录的情况
        return
    }
    
    user.multiFactor.getSessionWithCompletion { [weak self] session, error in
        guard let self = self, let session = session else {
            // 处理获取多因素会话失败的情况
            return
        }
        
        let configuration = Configuration(
            requestCode: { phone, completion in
                // 发送多因素验证码
                PhoneAuthProvider.provider().verifyPhoneNumber(
                    phone,
                    uiDelegate: nil,
                    multiFactorSession: session
                ) { verificationID, error in
                    completion(verificationID, error)
                }
            },
            signIn: { verificationID, verificationCode, completion in
                // 生成多因素凭证与断言,完成注册
                guard let credential = PhoneAuthProvider.provider().credential(
                    withVerificationID: verificationID,
                    verificationCode: verificationCode
                ) else {
                    completion(NSError(domain: "AuthError", code: -1, userInfo: [NSLocalizedDescriptionKey: "生成凭证失败"]))
                    return
                }
                
                let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
                user.multiFactor.enroll(with: assertion, displayName: "手机号") { error in
                    completion(error)
                }
            }
        )
        
        let vc = PhoneVerificationController(configuration: configuration)
        vc.delegate = self
        self.present(vc, animated: true)
    }
}

关键说明

  • 先校验用户已登录,再获取多因素会话,避免空指针问题
  • requestCode闭包仅负责发送验证码,将verificationID通过completion传递给下一步
  • signIn闭包接收verificationID和用户输入的验证码,完成多因素注册流程
  • 添加必要的错误处理,替换强制解包逻辑,提升代码稳定性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:15:45