Flutter集成Firebase电话认证时出现SafetyNet认证失败及类缺失问题
看起来你在集成Firebase电话认证时碰到了两个核心问题,还有代码里的一个潜在bug,我来帮你一步步解决:
1. 先搞定NoClassDefFoundError致命错误
错误日志里最显眼的就是java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/browser/customtabs/CustomTabsIntent$Builder;——这是因为你的Android项目缺少了Firebase电话认证依赖的androidx.browser库,Recaptcha验证环节需要用到它。
解决方法很简单:
打开android/app/build.gradle文件,在dependencies代码块中添加以下依赖:
implementation 'androidx.browser:browser:1.6.0' // 可以替换成最新版本号
添加后执行flutter clean清理缓存,再重新运行项目,这个类找不到的问题应该就能消失。
2. 处理SafetyNet校验失败的问题
日志里的SafetyNet Attestation fails basic integrity在模拟器上非常常见,毕竟模拟器的设备完整性很难通过SafetyNet的基础校验。你可以尝试这几个方案:
- 优先用真实设备测试:真实设备基本都能通过SafetyNet校验,这是最省心的方式。
- 启用Recaptcha fallback:在Firebase控制台的「电话认证」设置里,开启Recaptcha验证选项。当SafetyNet校验失败时,Firebase会自动切换到Recaptcha网页验证,这样在模拟器上也能完成认证流程。
- 再次核对SHA-256密钥:虽然你说已经更新了,但要确认添加的是debug版本的SHA-256(本地debug运行时用的是这个)。可以用这条命令查看debug密钥的SHA-256:
然后对比Firebase控制台里的配置,确保完全一致。keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
3. 修复代码里的Context未初始化bug
你的phoneLogin函数里声明了BuildContext context;但根本没赋值,这会导致codeSent回调里调用Navigator.push时触发空指针异常!
修改函数,把context作为参数传入:
Future phoneLogin(String phone, BuildContext context) async { // 新增context参数 try { await auth.verifyPhoneNumber( phoneNumber: '+91$phone', timeout: const Duration(seconds: 30), verificationCompleted: (PhoneAuthCredential credentials) async { await auth.signInWithCredential(credentials); }, verificationFailed: (FirebaseAuthException exception) { // 这里建议添加错误提示,提升用户体验 ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(exception.message ?? '电话认证失败')), ); }, codeSent: (String verificationId, [int forcedResendingToken]) { Navigator.push( context, MaterialPageRoute( builder: (BuildContext context) => OtpPage(phone: phone), ), ); }, codeAutoRetrievalTimeout: (String abc) {}); return null; } catch (e) { // 捕获全局异常并提示 ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(e.toString())), ); return null; } }
调用这个函数的时候,记得传入当前页面的context,比如在按钮点击事件里:
onPressed: () => phoneLogin(yourPhoneNumber, context),
最后总结
按顺序先解决依赖缺失问题,再修复代码里的context bug,最后根据你的测试环境选择SafetyNet的解决方案(真实设备或Recaptcha),这样应该就能顺利跑通电话认证流程了。
内容的提问来源于stack exchange,提问作者Himanshu Rai

