启用App Check的Firebase手机号认证:OTP接收不稳定且频繁出现配额超限(错误码39)等问题
启用App Check的Firebase手机号认证:OTP接收不稳定且频繁出现配额超限(错误码39)等问题
我最近在做Flutter应用的Firebase手机号认证功能,并且强制启用了App Check(Android端用Play Integrity,iOS端用App Attest),结果遇到了一个非常头疼的问题:OTP短信的送达情况完全不一致。有的手机号/设备能立刻收到OTP,可有的却完全收不到,还频繁抛出各种错误——哪怕我当天的SMS使用量是0,而且已经开通了Blaze付费计划。
预期与实际情况对比
- 预期效果:所有支持设备上的有效手机号都能稳定接收OTP短信,启用App Check后不会莫名其妙出现配额错误,也不会触发不必要的验证码验证。
- 实际情况:部分号码秒收OTP,另一部分则完全收不到短信,同时伴随
quota-exceeded(错误码39)、too-many-requests、unknown这类错误。哪怕当日SMS用量为0,问题依然存在,而且跨不同运营商和网络都出现了这个情况。另外,App Check令牌是有效的,应用是通过Play Store内部测试和TestFlight分发的。
初始化配置
我的Flutter应用初始化代码如下,同时已经配置了Crashlytics和错误处理机制:
await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); await FirebaseAppCheck.instance.activate( androidProvider: AndroidProvider.playIntegrity, appleProvider: AppleProvider.appAttest, );
Android端详细配置
- 已经完成Firebase基础配置,添加了最新的
google-services.json文件; - 把Debug、Release环境的SHA密钥(包括App Integrity的SHA)都添加到了Firebase后台;
- 已经将
.aab包上传到Play Console的内部测试渠道; - 启用了App Check,后台显示状态为“registered”,并且设置为强制模式;
- 在GCP里把客户端ID加入了App Check(Play Integrity)的白名单;
build.gradle的配置如下:dependencies { implementation(platform("com.google.firebase:firebase-bom:33.13.0")) implementation("com.google.firebase:firebase-auth") implementation("com.google.firebase:firebase-analytics") implementation("com.google.firebase:firebase-crashlytics") } plugins { id("com.google.gms.google-services") id("com.google.firebase.crashlytics") }- 已经启用并限制了12个必要API:Token Service API、Identity Toolkit API、Firebase Installations API、Firebase Management API、Firebase App Check API、Firebase App Distribution API、FCM Registration API、Firebase Cloud Messaging API、Firebase Hosting API、Google Play Integrity API、reCAPTCHA Enterprise API、Analytics Hub API。
iOS端详细配置
- 上传了APNs密钥和
.p12证书,用于推送通知和App Check验证; - 完成了App Attest的配置:已注册并关联了Team ID;
- 在
info.plist中添加了编码后的App ID作为自定义URL Scheme; - 导入了Firebase提供的
Google-Services-info.plist文件; - 启用了Firebase的Google签名功能;
- 在Google Cloud Console中启用了和Android端相同的12个API;
- 配置了包含推送通知权限的描述文件;
- 因为没有Mac设备,我是通过Codemagic部署的,所以在预脚本里添加了entitlements配置:
cat > ios/Runner/Runner.entitlements << 'EOF' <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>aps-environment</key> <string>production</string> <key>com.apple.developer.devicecheck.appattest-environment</key> <string>production</string> <key>com.apple.developer.background-modes</key> <array> <string>remote-notification</string> </array> </dict> </plist> EOF info.plist里的相关配置:<key>UIBackgroundModes</key> <array> <string>remote-notification</string> </array>
版本信息
- Firebase Core版本:
^3.13.0 - Flutter版本:
3.29.2 - Flutter依赖详情:
firebase_core: ^3.13.0 firebase_auth: ^5.5.3 firebase_app_check: ^0.3.2+5 firebase_messaging: ^15.2.5 firebase_storage: ^12.4.5 firebase_crashlytics: ^4.3.7 firebase_analytics: ^11.5.0
相关错误日志输出
Error details: [firebase_auth/unknown] An internal error has occurred. [ Error code:39 ] verificationFailed: quota-exceeded verificationFailed: too-many-requests verificationFailed: unknown verificationFailed: 39
内容来源于stack exchange




