firebase - Android 上的 Firebase 电话身份验证
问题描述
我已经正确实现了 Firebase 电子邮件和 Google 登录,它在 iOS 和 Android 上都可以正常工作。然后我尝试实现 Over the Phone Auth,首先它在 iPhone 上不起作用,但后来我做了一些研究,似乎我必须上传一些 APN,最后我正确设置它,现在它在 iPhone 上工作,但是当我尝试向 Android 发送 SMS 时,它没有收到它,而是向我发送了一条消息,表明代码已像在 iPhone 上一样发送。
最奇怪的是,如果我输入 iPhone 的手机号码,它会收到 SMS 代码。所以我想知道我是否必须像在 iPhone 上那样在 Android 上启用某种类型的推送通知,或者我是否必须设置一些真正的开发者帐户,因为现在我没有谷歌的帐户,或者我还有别的东西米失踪。
有人可以帮我解决这个问题吗?
我使用的 auth 方法是 Flutter 示例之一:
class _PhoneSignInSection extends StatefulWidget {
_PhoneSignInSection(this._scaffold);
final ScaffoldState _scaffold;
@override
State<StatefulWidget> createState() => _PhoneSignInSectionState();
}
class _PhoneSignInSectionState extends State<_PhoneSignInSection> {
final TextEditingController _phoneNumberController = TextEditingController();
final TextEditingController _smsController = TextEditingController();
String _message = '';
String _verificationId;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: const Text('Test sign in with phone number'),
padding: const EdgeInsets.all(16),
alignment: Alignment.center,
),
TextFormField(
controller: _phoneNumberController,
decoration:
InputDecoration(labelText: 'Phone number (+x xxx-xxx-xxxx)'),
validator: (String value) {
if (value.isEmpty) {
return 'Phone number (+x xxx-xxx-xxxx)';
}
return null;
},
),
Container(
padding: const EdgeInsets.symmetric(vertical: 16.0),
alignment: Alignment.center,
child: RaisedButton(
onPressed: () async {
_verifyPhoneNumber();
},
child: const Text('Verify phone number'),
),
),
TextField(
controller: _smsController,
decoration: InputDecoration(labelText: 'Verification code'),
),
Container(
padding: const EdgeInsets.symmetric(vertical: 16.0),
alignment: Alignment.center,
child: RaisedButton(
onPressed: () async {
_signInWithPhoneNumber();
},
child: const Text('Sign in with phone number'),
),
),
Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
_message,
style: TextStyle(color: Colors.red),
),
)
],
);
}
// Example code of how to verify phone number
void _verifyPhoneNumber() async {
setState(() {
_message = '';
});
final PhoneVerificationCompleted verificationCompleted =
(AuthCredential phoneAuthCredential) {
_auth.signInWithCredential(phoneAuthCredential);
setState(() {
_message = 'Received phone auth credential: $phoneAuthCredential';
});
};
final PhoneVerificationFailed verificationFailed =
(AuthException authException) {
setState(() {
_message =
'Phone number verification failed. Code: ${authException.code}. Message: ${authException.message}';
});
};
final PhoneCodeSent codeSent =
(String verificationId, [int forceResendingToken]) async {
widget._scaffold.showSnackBar(SnackBar(
content:
const Text('Please check your phone for the verification code.'),
));
_verificationId = verificationId;
};
final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
(String verificationId) {
_verificationId = verificationId;
};
await _auth.verifyPhoneNumber(
phoneNumber: _phoneNumberController.text,
timeout: const Duration(seconds: 5),
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: codeSent,
codeAutoRetrievalTimeout: codeAutoRetrievalTimeout);
}
// Example code of how to sign in with phone.
void _signInWithPhoneNumber() async {
final AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: _verificationId,
smsCode: _smsController.text,
);
final FirebaseUser user =
(await _auth.signInWithCredential(credential));
final FirebaseUser currentUser = await _auth.currentUser();
assert(user.uid == currentUser.uid);
setState(() {
if (user != null) {
_message = 'Successfully signed in, uid: ' + user.uid;
} else {
_message = 'Sign in failed';
}
});
}
}
而我的 App 级别 build.gradle 具有以下依赖项:
dependencies {
implementation 'com.google.firebase:firebase-auth:19.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
正如指南所说:
将 Firebase Authentication Android 库的依赖项添加到您的模块(应用级)Gradle 文件(通常是 app/build.gradle): implementation 'com.google.firebase:firebase-auth:19.0.0'
当然我 apply plugin: 'com.google.gms.google-services'
在同一个 build.gradle
编辑:当它使用列入白名单的电话号码进行测试时,我在 Android 上成功登录。
解决方案
iPhone 中的电话号码正在成功接收来自 Android 和 iOS 应用程序的短信。
Android 中的电话号码未收到来自 Android 或 iOS 应用程序的任何短信。
所以问题不在于应用程序,而在于 Android 手机中的电话号码/SIM。如果电话在路上,或者电话号码没有任何限制,则可能会发生这种情况,那么 Firebase 可能不会发送 SMS。显然这就是正在发生的事情。为确保这是问题所在,最好使用另一个电话号码进行测试。如果它使用新的电话号码,我们可以用特定的电话号码而不是你的手机来总结它的问题。
您可能想要重写以下代码(在那些行中):
_auth.signInWithCredential(phoneAuthCredential);
setState(() {
_message = 'Received phone auth credential: $phoneAuthCredential';
});
至
_auth.signInWithCredential(phoneAuthCredential)
.then((user) {setState(){
_message = 'Received phone auth credential: $phoneAuthCredential';
}})
.catchError((error) {
_message = 'Something went wrong: $error';
});
这样您就可以确保_auth.signInWithCredential
在通知用户之前确保成功。
推荐阅读
- javascript - 单击时将类添加到 HTML 列表中的一个且只有一个元素
- webpack - babel.loader 和 pluginPass.CallExpression 错误
- c - 如何播放和回放小c程序
- c# - 西里尔符号显示为问号。内容类型:文本/xml;字符集=windows-1251;
- python - 带有多行字段的 Pandas Read_CSV
- javascript - 在文件之间导出和导入数据
- authentication - 使用 AAD 将 SAML 交换为 JWT
- django - 具有自定义 uer 模型的 Social-auth-django 使用 OneToOneField 链接到 auth.User
- php - 如何从 php 中的文件中获取方法代码而不删除回行和制表符
- reactjs - 是否可以使用 XHR 上传模式将 Uppy 与拖放一起使用?