Flutter应用Play Store版本Firebase电话认证OTP验证失败排查
Flutter Play Store版本Firebase电话认证OTP错误排查
问题现象
Flutter应用在Play Store发布版本中出现Firebase电话认证异常:用户输入手机号后,通过_firebaseAuth.verifyPhoneNumber完成验证跳转至OTP页面,输入正确OTP却弹出提示:sms code has expired please resend the sms code and try again。调试和内部测试阶段无此问题,Google Cloud Identity Toolkit API中google.cloud.identitytoolkit.v1.AuthenticationService.SignInWithPhoneNumber错误率达53%,推测问题与代码逻辑相关,但无法定位根源。
已完成的配置排查
- 使用Play控制台的upload-key签名应用,通过Asset Link Tools确认:调试应用显示Upload key证书SHA-256,Play Store应用显示App signing key证书SHA-256
- 已将所有SHA-1/SHA-256密钥添加至Firebase项目设置
- AppCheck配置:
await FirebaseAppCheck.instance.activate( webRecaptchaSiteKey: _webKey, androidProvider: kDebugMode ? AndroidProvider.debug : AndroidProvider.playIntegrity, appleProvider: AppleProvider.appAttest, );
相关代码片段
utils.dart
class AuthProvider extends ChangeNotifier { final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; void signInWithPhone(BuildContext context, String phoneNumber, Function() onVerificationSuccess) async { try { await _firebaseAuth.verifyPhoneNumber( phoneNumber: phoneNumber, verificationCompleted: (PhoneAuthCredential phoneAuthCredential) async { await _firebaseAuth.signInWithCredential(phoneAuthCredential); }, verificationFailed: (error) { toastBar(context, error.message.toString()); }, codeSent: (verificationId, forceResendingToken) { Navigator.of(context).push(createRoute(LoginScreen2( phone: phoneNumber, verficationId: verificationId, ))); onVerificationSuccess(); }, timeout: const Duration(seconds: 60), codeAutoRetrievalTimeout: (verificationId) { showSnackBar(context, 'OTP retrieval timed out. Please try again.'); }); } on FirebaseAuthException catch (e) { toastBar(context, e.message.toString()); } } void verifyOtp({ required BuildContext context, required String verificationId, required String userOtp, required Function onSuccess, }) async { notifyListeners(); try { PhoneAuthCredential creds = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: userOtp); User? user = (await _firebaseAuth.signInWithCredential(creds)).user; if (user != null) { // carry our logic onSuccess(); } notifyListeners(); } on FirebaseAuthException catch (e) { showSnackBar(context, e.message.toString()); notifyListeners(); } } Future userSignOut() async { await _firebaseAuth.signOut(); notifyListeners(); } }
otp.dart
// verify otp void verifyOtp(BuildContext context, String userOtp) { final ap = Provider.of<AuthProvider>(context, listen: false); ap.verifyOtp( context: context, verificationId: widget.verficationId, userOtp: userOtp, onSuccess: () { // checking whether user exists in the db uid = FirebaseAuth.instance.currentUser?.uid; FirebaseFirestore.instance .collection('Users') .doc(uid) .get() .then((value) async { // handles the sucess }); }, ); }
login.dart
void sendPhoneNumber() { setState(() { _loading = true; }); final ap = Provider.of<AuthProvider>(context, listen: false); ap.signInWithPhone( context, "+91${_controller.text}", () { // Callback function: invoked after verification and navigation setState(() { _loading = false; }); // Perform any additional actions here }, ); }
疑问与求助
曾考虑移除verificationCompleted回调中重复的_firebaseAuth.signInWithCredential(creds)调用,但担心丢失自动登录功能,希望得到问题根源的排查方向与解决方案。
内容的提问来源于stack exchange,提问作者ItsHarsh.json
相关产品推荐
相关产品推荐

