首页 > 解决方案 > Flutter FirebaseAuth 不向手机发送验证码

问题描述

我正在尝试在我的应用程序中添加一项功能,该功能允许用户通过向他们的电话号码发送代码来验证他们的电话号码。我发现我可以通过使用 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

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

标签: firebaseflutterfirebase-authentication

解决方案


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

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

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

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 : 显示用户 ashowDialog手动输入代码。有关更多信息,请访问中篇文章,完整代码请访问github 存储库


推荐阅读