如何在 Flutter 中使用 Firebase 电话身份验证?

时间:2021-03-15 07:37:46

标签: android firebase flutter firebase-authentication

我正在尝试使用 flutter 和 firebase 制作应用程序。我正在使用 FirebaseAuth 进行注册和登录。我将手机号码和密码作为输入并创建一个带有电话号码的虚拟电子邮件并使用 firebase auth signInWithEmailPassword 登录。我想要做的是第一次用户注册时,我想将 otp 发送到该号码,如果号码经过验证,我想使用该虚拟电子邮件和密码进行注册。任何想法如何实现这一目标。我尝试了一些东西,但即使 otp 错误,用户仍在注册。

 String email = '';
 String password = '';
 String name = '';
 String contact = '';
 String error = '';
 String smsCode = '';
 String verificationId;
 bool loading = false;

 Future<void> verifyPhone() async {
print('Inside verify phone');
final PhoneCodeAutoRetrievalTimeout autoRetrieve = (String verId) {
  this.verificationId = verId;
};

final PhoneCodeSent smsCodeSent = (String verId, [int forceCodeResend]) {
  this.verificationId = verId;
  print('Inside code sent');
  smsCodeDialog(context).then((value) {
    print('Signed in');
  });
};

final PhoneVerificationCompleted verifiedSuccess =
    (AuthCredential credential) {
  print('verified');
};

final PhoneVerificationFailed verificationFailed =
    (AuthException exception) {
  print('${exception.message}');
};

if (_formKey.currentState.validate()) {
  await FirebaseAuth.instance.verifyPhoneNumber(
    phoneNumber: '+91 ' + contact,
    timeout: const Duration(seconds: 10),
    verificationCompleted: verifiedSuccess,
    verificationFailed: verificationFailed,
    codeSent: smsCodeSent,
    codeAutoRetrievalTimeout: autoRetrieve,
  );
}
 }

 Future<bool> smsCodeDialog(BuildContext context) {
return showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return new AlertDialog(
        title: Text('Enter SMS Code'),
        content: TextField(
          onChanged: (value) {
            this.smsCode = value;
          },
        ),
        contentPadding: EdgeInsets.all(10),
        actions: <Widget>[
          TextButton(
              onPressed: () async {
                dynamic result =
                    await _auth.register(email, password, name, contact);
                if (result == null) {
                  Navigator.pop(context);
                  setState(() {
                    loading = false;
                    error = "Already registered or Invalid Details.";
                  });
                } else {
                  Navigator.pop(context);
                  Navigator.pushNamedAndRemoveUntil(
                      context, '/', (Route<dynamic> route) => false);
                }
              },
              child: Text('Register',
                  style: GoogleFonts.abhayaLibre(
                      textStyle: TextStyle(
                          fontSize: 24, color: Colors.green[900]))))
        ],
      );
    });
 }

在提交表单时,我调用了 verifyPhone 方法。

1 个答案:

答案 0 :(得分:0)

Future<bool> signIn() async {
try {
  final AuthCredential credential = PhoneAuthProvider.getCredential(
    verificationId: verificationId,
    smsCode: smsCode,
  );
  final AuthResult userResult =
      await _auth.signInWithCredential(credential);
  final FirebaseUser currentUser = await _auth.currentUser();

  final document =
      Firestore().collection("users").document(currentUser.uid);
  final documentSnapshot = await document.get();
  if (!documentSnapshot.exists) {
    await document.setData({
      "id": currentUser.uid,
      "number": phoneNumber,
    });
  }
  return true;
} catch (e) {
  return false;
}

}

  onPressed: () async {
                                      if (_smsController.text.isEmpty) {
                                        widget.scaffoldKey.currentState
                                            .showSnackBar(SnackBar(
                                          content: Text(
                                              "Please enter your SMS code"),
                                          duration: Duration(seconds: 2),
                                        ));
                                        return;
                                      }

                                      await _auth
                                          .currentUser()
                                          .then((user) async {
                                        await signIn()
                                            .then((bool isSignedIn) async {
                                          if (isSignedIn) {
                                            Navigator.of(context)
                                                .pushAndRemoveUntil();
                                          } else {
                                            widget.scaffoldKey.currentState
                                                .showSnackBar(SnackBar(
                                              content:
                                                  Text("Incorrect Code"),
                                              duration:
                                                  Duration(seconds: 2),
                                            ));
                                          }
                                        });
                                      });
                                    },

在这里我可以向您展示一个最小的示例,该示例还使用 firestore 为用户存储额外信息,每当按下 SMS 对话框的按钮时就会触发 onPressed