Flutter中Firebase OTP自动验证失效 onVerificationCompleted未触发
Flutter Firebase OTP自动验证不触发修复方案
问题表现:原生Android端Firebase OTP自动验证正常,Flutter端短信送达后
verificationCompleted回调始终不触发。
基础配置排查
- 升级依赖版本:低版本
firebase_auth(4.0以下)存在大量Android端短信自动检索兼容bug,执行flutter pub upgrade firebase_core firebase_auth升级到最新稳定版,确保两个依赖版本匹配。 - 检查Android构建配置:模块级
build.gradle中minSdkVersion需设置为21及以上,低于该版本不支持Firebase依赖的SmsRetriever API。 - 重新同步Firebase配置:执行
flutterfire configure重新生成配置文件,避免迁移过程中google-services.json与Flutter端初始化参数不匹配,导致底层短信监听服务未正确注册。 - 确认签名配置:debug、release签名对应的SHA-1、SHA-256都要添加到Firebase控制台的Android应用配置中,签名不匹配时Google Play服务会拒绝返回短信解析结果。
Android端清单文件修复
这是原生迁Flutter项目最容易踩的坑,按以下要求调整AndroidManifest.xml:
- 添加必要权限(放在manifest根节点下):
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="com.google.android.gms.auth.api.phone.permission.SMS"/>
注意:Firebase自动验证依赖Google Play服务的无权限短信读取能力,不需要额外添加RECEIVE_SMS/READ_SMS权限,也不需要动态申请短信权限,自行添加这类权限反而可能触发系统限制,导致自动读取失败。
2. 删除所有自定义的短信接收广播接收器:原生项目中如果注册过监听SMS_RECEIVED动作的自定义广播,会抢占SmsRetriever的广播通道,导致Firebase无法收到短信解析结果,这类配置必须从Flutter模块的清单文件中移除。
3. 代码混淆规则补充:如果开启了R8代码混淆,在proguard规则文件中添加以下配置,避免回调被混淆吞掉:
-keep class com.google.firebase.auth.** { *; } -keep class com.google.android.gms.auth.api.phone.** { *; }
代码逻辑修正
当前实现存在几个逻辑问题,按以下方式调整:
verificationCompleted回调触发的前提是Google Play服务成功解析短信、生成合法的认证凭证,不要只在回调里取smsCode,直接用凭证完成登录即可,参考实现:
verificationCompleted: (PhoneAuthCredential credential) async { try { // 直接用返回的凭证登录,不需要手动提取验证码填充 final UserCredential userCred = await auth.signInWithCredential(credential); // 编写登录成功后的跳转/业务逻辑 } catch (e) { // 自动登录失败时降级到手动输入验证码流程 } },
codeSent回调触发时仅代表验证码短信已成功下发,此时后台的短信自动检索监听仍在运行,不要在这个回调里执行页面销毁、监听暂停、Auth实例重置类操作,注释中的_controller.resume如果涉及页面栈切换或监听暂停,会导致后续回调找不到接收方。- 测试时不要使用模拟器,必须用安装了最新版Google Play服务、已登录Google账号的真机,测试手机号不要开启Google账号二次验证,否则自动验证流程会被安全策略拦截。
验证步骤
修改完成后先卸载测试机上的旧安装包,执行flutter clean后重新构建安装,触发发送验证码后保持应用在前台等待5-10秒,正常情况下verificationCompleted会自动触发完成登录,不需要用户手动输入验证码。
内容的提问来源于stack exchange,提问作者Arif
相关产品推荐
相关产品推荐

