Flutter出租车应用Firebase OTP发送失败:17028权限错误求助
问题:Flutter Firebase OTP验证码发送失败(错误17028)
错误日志
[SmsRetrieverHelper] SMS verification code request failed: unknown status code: 17028 Invalid app info in play_integrity_token D/FirebaseAuth(19555): Invoking original failure callbacks after phone verification failure for +970 569292492, error - This app is not authorized to use Firebase Authentication. Please verify that the correct package name, SHA-1, and SHA-256 are configured in the Firebase Console. [ Invalid app info in play_integrity_token ] E/flutter (19555): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: [firebase_auth/app-not-authorized] This app is not authorized to use Firebase Authentication. Please verify that the correct package name, SHA-1, and SHA-256 are configured in the Firebase Console. [ Invalid app info in play_integrity_token ] E/flutter (19555): #0 AuthServices.loginWithOTP.<anonymous closure> (package:taxi_driver/Services/AuthService.dart:206:11) E/flutter (19555): #1 MethodChannelFirebaseAuth.verifyPhoneNumber.<anonymous closure> (package:firebase_auth_platform_interface/src/method_channel/method_channel_firebase_auth.dart:631:29) E/flutter (19555): #2 _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10) E/flutter (19555): #3 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:365:11) E/flutter (19555): #4 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:297:7) E/flutter (19555): #5 _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:123:11) E/flutter (19555): #6 _HandleErrorStream._handleData (dart:async/stream_pipe.dart:253:10) E/flutter (19555): #7 _ForwardingStreamSubscription._handleData (dart:async/stream_pipe.dart:153:13) E/flutter (19555): #8 _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10) E/flutter (19555): #9 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:365:11) E/flutter (19555): #10 _DelayedData.perform (dart:async/stream_impl.dart:541:14) E/flutter (19555): #11 _PendingEvents.handleNext (dart:async/stream_impl.dart:646:11) E/flutter (19555): #12 _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:617:7) E/flutter (19555): #13 _microtaskLoop (dart:async/schedule_microtask.dart:40:21) E/flutter (19555): #14 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
已确认信息
- 已在Firebase控制台为应用添加SHA-1和SHA-256指纹
- 应用通知功能正常运行
相关代码
Firebase初始化代码
await Firebase.initializeApp( options: const FirebaseOptions( apiKey: 'AIzaSyCPeRJrJwY6u78FjKsAyxk9VUTRZ_Gn6Q4', appId: '1:211011031878:android:616945e871967f09084b47', messagingSenderId: '211011031878', projectId: 'classystore-b84cd', storageBucket: 'classystore-b84cd.appspot.com', ), ).then((value) { FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError; });
android/build.gradle配置
buildscript { // ext.kotlin_version = '1.8.20' repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:7.4.2' // classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.google.gms:google-services:4.4.2' } } allprojects { repositories { google() mavenCentral() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { project.evaluationDependsOn(':app') } tasks.register("clean", Delete) { delete rootProject.buildDir }
android/app/build.gradle配置
plugins { id "com.android.application" id "kotlin-android" id "dev.flutter.flutter-gradle-plugin" id "com.google.gms.google-services" } def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } //apply plugin: 'com.android.application' //apply plugin: 'kotlin-android' //apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" //apply plugin: 'com.google.gms.google-services' android { compileSdkVersion 34 compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { jvmTarget = '1.8' } sourceSets { main.java.srcDirs += 'src/main/kotlin' } defaultConfig { applicationId "com.mighty.taxidriver" minSdkVersion 23 targetSdkVersion 34 versionCode 17 versionName '2.2.1' } buildTypes { release { signingConfig signingConfigs.debug minifyEnabled false shrinkResources false } } buildToolsVersion '29.0.3' } flutter { source '../..' } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.10" implementation platform('com.google.firebase:firebase-bom:33.1.2') implementation 'androidx.multidex:multidex:2.0.1' // implementation 'com.mercadopago.android.px:checkout:4.+' implementation('com.braintreepayments.api:drop-in:5.2.1'){ exclude group: "org.jfrog.cardinalcommerce.gradle", module: "cardinalmobilesdk" } implementation("org.jfrog.cardinalcommerce.gradle:cardinalmobilesdk:2.2.7-2") }
OTP登录逻辑代码
Future<void> loginWithOTP(BuildContext context, String phoneNumber) async { return await _auth.verifyPhoneNumber( phoneNumber: phoneNumber, verificationCompleted: (PhoneAuthCredential credential) async {}, verificationFailed: (FirebaseAuthException e) { if (e.code == 'invalid-phone-number') { toast('The provided phone number is not valid.'); throw 'The provided phone number is not valid.'; } else { toast(e.toString()); throw e.toString(); } }, codeSent: (String verificationId, int? resendToken) async { Navigator.pop(context); appStore.setLoading(false); await showDialog( context: context, builder: (context) => AlertDialog(content: OTPDialog(verificationId: verificationId, isCodeSent: true, phoneNumber: phoneNumber)), barrierDismissible: false, ); }, codeAutoRetrievalTimeout: (String verificationId) { // }, ); }
排查与解决方案
核对包名一致性
确认android/app/build.gradle中的applicationId(com.mighty.taxidriver)与Firebase控制台对应应用的包名完全一致,包括大小写、特殊字符。验证SHA指纹正确性
- 运行以下命令获取当前应用签名证书的指纹(debug环境):
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android - 将输出的SHA-1和SHA-256与Firebase控制台中配置的指纹对比,确保完全匹配;若使用正式签名证书,需对应替换命令中的keystore路径和密码。
- 若切换了Build Variants,需为对应build类型添加匹配的指纹。
- 运行以下命令获取当前应用签名证书的指纹(debug环境):
更新Firebase配置文件
- 从Firebase控制台重新下载最新的
google-services.json文件,替换android/app目录下的旧文件,禁止手动修改文件内容。 - 核对代码中
FirebaseOptions的参数(apiKey、projectId、appId等)与google-services.json中的对应字段一致。
- 从Firebase控制台重新下载最新的
检查Play Integrity配置
- 错误提示关联
play_integrity_token,需确保Google Play Console中已为应用启用Play Integrity API,且Firebase项目关联了正确的Google Play项目。 - 测试环境下,可临时在Firebase控制台的Authentication -> Sign-in method -> Phone中关闭"Play Integrity"验证(正式环境必须开启)。
- 错误提示关联
清理缓存并重建项目
- 执行
flutter clean,删除android/.gradle文件夹,再依次运行flutter pub get和flutter run。 - 可尝试更新gradle和google-services插件到最新稳定版,确保兼容性。
- 执行
确认Firebase Authentication权限
- 检查Firebase控制台中Authentication -> Sign-in method,确保Phone sign-in方法已启用,且无额外限制规则。
内容的提问来源于stack exchange,提问作者Mahmoud Ayyash
相关产品推荐
相关产品推荐

