Firebase 电话身份验证:某些用户未收到 OTP

时间:2021-02-13 15:41:15

标签: firebase flutter firebase-authentication

我面临一个奇怪的问题,有些电话号码没有收到 OTP 没有收到任何错误,只是没有任何反应。除了极少数用户之外,几乎所有用户都可以很好地接收 OTP。我该如何调试问题? Firebase 身份验证是否有一些错误的日志?我的代码是否遗漏了什么?

这是发送 OTP 的代码(在 Flutter 中)

sendOtp(String number, BuildContext context) async {
    print("Sending OTp");
    state = ViewState.Busy;
    await auth.verifyPhoneNumber(
      phoneNumber: '+966$number',
      timeout: Duration(seconds: 30),
      verificationCompleted: (AuthCredential credential) {
        print("Verified");
        signInWCredential(credential, context, number);
      },
      verificationFailed: (FirebaseAuthException e) {
        print("verification error code is: ${e.code}");
        print("verification error message is: ${e.message}");
        if (e.code == "too-many-requests") {
          Dialogs.dialog(
                  context,
                  "${Localization.of(context).error}!",
                  Localization.of(context).tooManyOtpRequestsError,
                  Localization.of(context).ok,
                  isDoublePop: true)
              .then((value) {
            if (value == ConfirmAction.ACCEPT) {
              Navigator.of(context).pop();
            }
          });
        } else {
          FirebaseCrashlytics.instance.recordError(e, StackTrace.current);
          print("Error is: $e");
          Dialogs.dialog(
              context,
              "${Localization.of(context).error}!",
              Localization.of(context).errorSendingOtp,
              Localization.of(context).ok,
              isDoublePop: true);
        }
      },
      codeSent: (String verificationId, [int resendToken]) {
        print("Code sent");
        print("verification ID is: $verificationId");
        setVerificationId(verificationId);
        print("Resend token is: $resendToken");
        state = ViewState.Idle;
      },
      codeAutoRetrievalTimeout: (String verificationId) {},
    );
  }

3 个答案:

答案 0 :(得分:0)

import 'package:firebase_auth/firebase_auth.dart';  
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class Demo extends StatefulWidget {
  @override
  _DemoState createState() => _DemoState();
}

class _DemoState extends State<Demo> {
  TextEditingController _controller = TextEditingController();

Future<void> _showMyDialog() async {
return showDialog<void>(
  context: context,
  barrierDismissible: false, // user must tap button!
  builder: (BuildContext context) {
    return AlertDialog(
      title: Text('AlertDialog Title'),
      content: SingleChildScrollView(
        child: ListBody(
          children: <Widget>[
            Text('This is a demo alert dialog.'),
            TextField(
              controller: _controller,
            )
          ],
        ),
      ),
      actions: <Widget>[
        TextButton(
          child: Text('Approve'),
          onPressed: () {
            Navigator.of(context).pop();
          },
        ),
      ],
    );
  },
);
 }

  void sendOTP() async {
await FirebaseAuth.instance.verifyPhoneNumber(
  phoneNumber: "your number",
  verificationCompleted: (PhoneAuthCredential credential) async {
    print("verificationCompleted");
    await FirebaseAuth.instance.signInWithCredential(credential);
  },
  verificationFailed: (FirebaseAuthException e) {
    print("FirebaseAuthException");
    print(e.code);
  },
  codeSent: (String verificationID, int token) async {
    print("codeSent");
    await _showMyDialog();
    PhoneAuthCredential phoneAuthCredential = PhoneAuthProvider.credential(
        verificationId: verificationID, smsCode: _controller.text);
    await FirebaseAuth.instance.signInWithCredential(phoneAuthCredential);
    print("completed");
  },
  codeAutoRetrievalTimeout: (String verificationID) {
    print("$verificationID");
  },
  timeout: const Duration(seconds: 60),
);
 }

  @override
  Widget build(BuildContext context) {
return Scaffold(
  body: Center(
    child: FlatButton(
      child: Text(
          "send otp"),
      onPressed: sendOTP,
    ),
  ),
);
 }
}

这是我使用 firebase 进行电话身份验证的代码,它适用于许多手机号码

答案 1 :(得分:0)

我遇到了这个问题,并通过搜索互联网发现 Firebase 的电话身份验证对将其号码从一个网络移植到另一个网络的用户不起作用。我还发现其他电话身份验证 SDK(Firebase 除外)也有同样的问题。唯一的解决方案是让您的用户可以选择使用电子邮件和密码登录或电话身份验证以外的其他登录方法。提供这两个选项将保证用户可以登录。

答案 2 :(得分:0)

我已联系 GCP 支持人员调查此问题。他们向我报告说,我客户所在地区的短信发送成功率为 85%-90%。他们正在与 SMS 提供商合作解决该问题。

如果 SMS 传送失败,我提出了一个新功能请求以返回错误消息。同时,我通过创建自己的自定义身份验证 API 并通过其他服务提供商发送短信来解决此问题。