【问题标题】:Flutter FirebaseAuth not sending verification code to phoneFlutter FirebaseAuth 不向手机发送验证码
【发布时间】:2020-12-18 12:40:59
【问题描述】:

我正在尝试在我的应用中添加一项功能,允许用户通过向他们的电话号码发送代码来验证他们的电话号码。我发现我可以通过使用 firebase 来做到这一点。这是我发送验证码的方式:

 Future<void> verifyPhone() async {
void verificationCompleted(AuthCredential phoneAuthCredential) {
  print('verificationCompleted $phoneAuthCredential');
  _phoneAuthCredential = phoneAuthCredential;
  _db.updateUserField(userUid, {
    'isNumberConfirmed': true,
    'linkedAccounts': FieldValue.arrayUnion(['P-$phoneAuthCredential'])
  });
  currentUser.isNumberConfirmed = true;
  currentUser.linkedAccounts.add('P-$phoneAuthCredential');
  worked = true;
}

void verificationFailed(FirebaseAuthException error) {
  worked = false;
}

void codeSent(String verificationId, [int code]) {
  _code = code;
  _verificationId = verificationId;
  print('Code: $code\t_verificationId: $_verificationId');
}

void codeAutoRetrievalTimeout(String verificationId) {
  worked = false;
}

_auth.verifyPhoneNumber(
    phoneNumber: '+1${currentUser.phone}',
    timeout: Duration(milliseconds: 60000),
    verificationCompleted: verificationCompleted,
    verificationFailed: verificationFailed,
    codeSent: codeSent,
    codeAutoRetrievalTimeout: codeAutoRetrievalTimeout);

}

但是每当调用此方法时,我都会收到以下消息并且没有发送验证码:

I/BiChannelGoogleApi(25924): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzao@bafccce
W/DynamiteModule(25924): Local module descriptor class for com.google.firebase.auth not found.
I/FirebaseAuth(25924): [FirebaseAuth:] Preparing to create service connection to gms implementation

我不确定它为什么不发送代码。我错过了什么吗?

【问题讨论】:

  • 请分享更多登录验证码,否则我们无能为力。
  • @gladiator 我添加了完整的方法代码。

标签: firebase flutter firebase-authentication


【解决方案1】:

我发现你的代码很难调试,所以我分享这个:

首先确保您已在 firebase 控制台中启用电话登录方法, 并在pubspec.yaml中添加了Firebase Authentication插件和Firebase核心插件

像这样定义您的验证电话号码按钮:

onPressed: (){
                        //code for sign in
                        final mobile = _phoneTextBoxController.text.trim();
                        registerUser(mobile, context);
                    }

现在像这样定义整个验证过程:

Future registerUser(String mobile, BuildContext context) async{

  FirebaseAuth _auth = FirebaseAuth.instance;
  
  _auth.verifyPhoneNumber(
    phoneNumber: mobile,
    timeout: Duration(seconds: 60),
    verificationCompleted: (AuthCredential authCredential){
_auth.signInWithCredential(_credential).then((AuthResult result){
Navigator.pushReplacement(context, MaterialPageRoute(
    builder: (context) => HomeScreen(result.user)
  ));
}).catchError((e){
  print(e);
});
},
verificationFailed: (AuthException authException){
  print(authException.message);
},
codeSent:(String verificationId, [int forceResendingToken]){
  //show dialog to take input from the user
  showDialog(
  context: context,
  barrierDismissible: false,
  builder: (context) => AlertDialog(
    title: Text("Enter SMS Code"),
    content: Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        TextField(
          controller: _codeController,
        ),

      ],
    ),
    actions: <Widget>[
      FlatButton(
        child: Text("Done"),
        textColor: Colors.white,
        color: Colors.redAccent,
        onPressed: () {
          FirebaseAuth auth = FirebaseAuth.instance;
          
          smsCode = _codeController.text.trim();
          
          _credential = PhoneAuthProvider.getCredential(verificationId: verificationId, smsCode: smsCode);
          auth.signInWithCredential(_credential).then((AuthResult result){
            Navigator.pushReplacement(context, MaterialPageRoute(
              builder: (context) => HomeScreen(result.user)
            ));
          }).catchError((e){
            print(e);
          });
        },
      )
    ],
  )
);
},
codeAutoRetrievalTimeout: (String verificationId){
  verificationId = verificationId;
  print(verificationId);
  print("Timout");
}
);

那么上面的代码是做什么的?首先它将 OTP 代码发送给用户并尝试使用此代码登录:

verificationCompleted: (AuthCredential authCredential){
_auth.signInWithCredential(_credential).then((AuthResult result){
Navigator.pushReplacement(context, MaterialPageRoute(
    builder: (context) => HomeScreen(result.user)
  ));
}).catchError((e){
  print(e);
});
},

并将用户推送到主屏幕,您可以相应地更改上述代码以匹配您的应用主屏幕。如果自动检索失败,则codeSent : 向用户显示showDialog 以手动输入代码。更多信息请访问this中篇文章,完整代码请访问thisgithub存储库

【讨论】:

  • 对不起,我没有澄清这一点。这只是一个临时值,用于展示我正在传递一个电话号码
  • 请分享更多登录验证码,否则我们无能为力。
  • 谢谢你的回答,不过我还没测试,这几天比较忙。
猜你喜欢
  • 1970-01-01
  • 2021-05-13
  • 1970-01-01
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-21
相关资源
最近更新 更多