如何使用 firebase 在 flutter 中实现 phone 数字验证? (不是认证)

How to implement phone number verification in flutter using firebase? (Not Authentication)

如何使用 firebase 在 flutter 中实现 phone 数字验证?。我的应用程序需要在某个时间点验证 phone 号码。不需要通过 phone 号码进行身份验证。我只需要验证我的号码。我如何实现它?

在 Firebase phone 中,号码验证会自动对用户进行身份验证。如果用户不登录,则无法使用 Firebase 身份验证验证用户的 phone 号码。

手动执行,使用 PhoneNumberUtil class 和代码中的手动方法来验证国家/地区代码

该方法检查号码的国家代码,在这种情况下,我指定只允许使用国家代码 'KE'

的肯尼亚号码
 _checkPhoneNumber() async {
var s = phoneTextFieldController.text;
bool isValid;
if (s.length == 0) {
  isValid = true;
  setState(() {
    _isPhoneNumber = isValid;
  });
  return;
}
 //check if the number starts with '0' , or '07' or '254'
if (s.length < 10) {
  isValid = s.length == 1 && s[0] == '0' ||
      s.length > 1 && s[0] + s[1] == '07' ||
      s.length > 1 && s[0] + s[1] + s[2] == '254' ||
      s.length > 1 && s[0] + s[1] + s[2] + s[3] == '+254';
  setState(() {
    _isPhoneNumber = isValid;
  });

  return;
}

isValid =
    await PhoneNumberUtil.isValidPhoneNumber(phoneNumber: s, isoCode: 'KE');
String normalizedNumber = await PhoneNumberUtil.normalizePhoneNumber(
    phoneNumber: s, isoCode: 'KE');
RegionInfo regionInfo =
    await PhoneNumberUtil.getRegionInfo(phoneNumber: s, isoCode: 'KE');

setState(() {
  _isPhoneNumber = isValid;
});
}

然后在你的表单中有

child: TextFormField(
                          onChanged: (text) {
                            _checkPhoneNumber();
                          },
                          controller: phoneTextFieldController,
                          keyboardType: TextInputType.phone,

                          validator: (val) {
                            if (val == '') {
                              return 'Phone Number is required';
                            }
                            if (!_isPhoneNumber) {
                              return 'Phone Number format error';
                            }
                          },
                          decoration: InputDecoration(
                              hintText: "2547xx xxx xxx - Phone",
                              border: InputBorder.none,
                              icon: const Icon(
                                Icons.phone,
                              ),
                              labelText: 'Phone',
                              prefixText: '     ',
                              suffixStyle:
                                  const TextStyle(color: Colors.green)),
                          onSaved: (value) {
                            phoneNumberForm = value;
                          },
                        )),

然后在提交表单时检查表单状态

 buttonCustom(
                  color: Color(0xFF4458be),
                  heigth: 50.0,
                  txt: contactIdParam!=null ?"Submit Edit":"Submit",
                  ontap: () {
                    final _form = form.currentState;
                    if (_form.validate()) {
                      if(contactIdParam!=null){
                         _editContactRequest();
                      }else{
                        _addContactRequest();

                      }

                    } else {
                      print('form is invalid');
                    }
                  },
                ),

注意:已从我的工作代码中复制了片段,我的验证与您想要的不同,但您需要的只是逻辑

在 firebase 中确实不能只验证 phone 号码,而 phone 号码验证会自动对用户进行身份验证,但这没关系。您可以 link 一个 phone 号码给已经通过身份验证的用户。链接 phone 号码意味着用户可以使用他们现有的提供商(gmail、Facebook、电子邮件等)登录,也可以使用他们的 phone 号码登录并使用相同的帐户密码.

查看示例 flutter 代码

_verifyPhoneNumber() async {
    await FirebaseAuth.instance.verifyPhoneNumber(
    phoneNumber: '+44 7123 123 456',
    verificationCompleted: (PhoneAuthCredential credential) {
     // For andriod only automatic handling of the SMS code
    },
    verificationFailed: (FirebaseAuthException e) {},
    codeSent: (String verificationId, int? resendToken) {
      // SMS Code sent show a dialogue to enter the code.
     _displayPhoneNumberVerificationDialog(verificationId);
    },
    codeAutoRetrievalTimeout: (String verificationId) {},
  );
}

_displayPhoneNumberVerificationDialog(verificationId) 内进行带有提交按钮的对话。 linking 逻辑将是按钮的 onTap。

示例 _displayPhoneNumberVerificationDialog

_displayPhoneNumberVerificationDialogSt(String verificationId) {
      FirebaseAuth firebaseAuth = firebase.FirebaseAuth.instance;
      return showDialog(
          context: context,
          builder: (context) {
            return AlertDialog(
              title: Text('Enter verification code'),
              content: TextField(
                keyboardType: TextInputType.number,
                textInputAction: TextInputAction.done,
                decoration: InputDecoration(hintText: "phone number"),
                onChanged: (input) {
                  _smsVerificationCode = input;
                },
              ),
              actions: <Widget>[
                new FlatButton(
                  child: new Text('Submit'),
                  onPressed: () async {
                    Navigator.of(context).pop();
                    // Create a PhoneAuthCredential with the code
                    PhoneAuthCredential credential;
                    try {
                      credential = PhoneAuthProvider.credential(
                          verificationId: verificationId,
                          smsCode: _smsVerificationCode);
                    } catch (e) {
                      // Show Error usually wrong _smsVerfication code entered
                      return;
                    }
                    User currentUser = await firebaseAuth.getCurrentUser();
                    try {
                      // This try catch helps if you want to update an existing verified phone number and you want to verify the new one.
                      // We unlink the old phone number so a new one can be linked
                      // This is not relevant if you're just going to verify and link a phone number without updating it later.
                      currentUser = await currentUser.unlink("phone");
                    } catch (e) {
                      print(e);
                      currentUser = await firebaseAuth.getCurrentUser();
                    }
                    try {
                      currentUser.linkWithCredential(credential).then((value) {
                        // Verfied now perform something or exit.
                      }).catchError((e) {
                        // An error occured while linking
                      });
                    } catch (e) {
                      // General error
                    }
                  },
                )
              ],
            );
          });
    }

有用的文档:https://firebase.flutter.dev/docs/auth/phone/

我见过的最佳选择是 Vonage。他们进行验证,发送大量 smsz 和 whatsapp 消息。这真是一项了不起的服务。