我正在使用 firebase flutter 实现电话身份验证。但是有一个问题
Posted
技术标签:
【中文标题】我正在使用 firebase flutter 实现电话身份验证。但是有一个问题【英文标题】:I am implementing phone authentication using firebase flutter. But there's a problem 【发布时间】:2021-06-05 01:16:39 【问题描述】:我想使用手机验证短信登录,每当新用户打开应用程序时,他都会输入他的电话号码并点击验证按钮,一旦点击,用户将在他的手机中收到一条验证短信,他将输入在验证文本字段中。但是当我运行该应用程序时,它会启动,当我输入电话号码并单击验证按钮时,该应用程序只是自行关闭而不是向我发送消息。代码如下:
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:sms_autofill/sms_autofill.dart';
Future<void> main() async
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.green,
),
home: MyHomePage(title: 'Flutter Auth Demo'),
);
class MyHomePage extends StatefulWidget
MyHomePage(Key key, this.title) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
class _MyHomePageState extends State<MyHomePage>
final FirebaseAuth _auth = FirebaseAuth.instance;
final _scaffoldKey = GlobalKey<ScaffoldState>();
final TextEditingController _phoneNumberController = TextEditingController();
final TextEditingController _smsController = TextEditingController();
String _verificationId;
final SmsAutoFill _autoFill = SmsAutoFill();
void verifyPhoneNumber() async
// Callback for when the user has already previously signed in with this phone no. on this device
PhoneVerificationCompleted verificationCompleted = (PhoneAuthCredential phoneAuthCredential) async
await _auth.signInWithCredential(phoneAuthCredential);
showSnackbar("Phone no. automatically verified and user signed in as: $_auth.currentUser.uid");
;
PhoneVerificationFailed verificationFailed = (FirebaseAuthException authException)
showSnackbar('Phone number verification failed. Code: $authException.code. Message:$authException.message');
;
// Callback for when the code is sent
PhoneCodeSent phoneCodeSent = (String verificationId,[int forceResendToken]) async
showSnackbar("Please check your phone for the verification code.");
_verificationId = verificationId;
;
PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout = (String verificationId) async
showSnackbar("Verification Code: "+verificationId);
_verificationId = verificationId;
;
try
await _auth.verifyPhoneNumber(
phoneNumber: _phoneNumberController.text,
timeout: const Duration(seconds: 5),
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: phoneCodeSent,
codeAutoRetrievalTimeout: codeAutoRetrievalTimeout
);
catch(e)
showSnackbar("Failed to verify phone number: $e");
void showSnackbar(String message)
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message)));
void signInWithPhoneNumber() async
try
final AuthCredential credential = PhoneAuthProvider.credential(
verificationId: _verificationId,
smsCode: _smsController.text
);
final User user = (await _auth.signInWithCredential(credential)).user;
showSnackbar("Successfully signed in with uid: $user.uid");
catch(e)
showSnackbar("Failed to sign in: "+e.toString());
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
key: _scaffoldKey,
resizeToAvoidBottomPadding: false,
body: Padding(padding: const EdgeInsets.all(8),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(
controller: _phoneNumberController,
decoration: const InputDecoration(
labelText: 'Phone number (+xx xxx-xxx-xxxx)'
),
),
Container(
padding: EdgeInsets.symmetric(vertical: 16.0),
alignment: Alignment.center,
child: RaisedButton(
child: Text("Get current number"),
onPressed: () async =>
_phoneNumberController.text = await _autoFill.hint,
print("_phoneNumberController.text: $_phoneNumberController.text")
,
color: Colors.greenAccent[700],
),
),
Container(
padding: EdgeInsets.symmetric(vertical: 16.0),
alignment: Alignment.center,
child: RaisedButton(
color: Colors.greenAccent[400],
child: Text("Verify Number"),
onPressed: () async
verifyPhoneNumber();
Navigator.of(context).pop();
),
),
TextFormField(
controller: _smsController,
decoration: const InputDecoration(labelText: 'Verification Code'),
),
Container(
padding: EdgeInsets.only(top: 16.0),
alignment: Alignment.center,
child: RaisedButton(
color: Colors.greenAccent[200],
onPressed: () async
signInWithPhoneNumber();
,
child: Text("Sign In"),
),
),
],
)
),
)
);
应用关闭时出现的错误是“设备连接丢失”:
E/androidRuntime(18860): 在 dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196) E/AndroidRuntime(18860): 在 java.lang.ClassLoader.loadClass(ClassLoader.java:379) E/AndroidRuntime (18860): 在 java.lang.ClassLoader.loadClass(ClassLoader.java:312) E/AndroidRuntime(18860): ... 12 更多 I/Process (18860): 发送信号。 PID:18860 SIG:9
【问题讨论】:
看看这个答案***.com/a/66039511/11039164 它对我有用,谢谢。 【参考方案1】:从此代码 sn-p remove Navigator.of(context).pop();
它使您的应用弹出关闭应用程序的唯一屏幕,并最终显示失去连接,因为应用程序不再可见。
Container(
padding: EdgeInsets.symmetric(vertical: 16.0),
alignment: Alignment.center,
child: RaisedButton(
color: Colors.greenAccent[400],
child: Text("Verify Number"),
onPressed: () async
verifyPhoneNumber();
Navigator.of(context).pop();
),
),
【讨论】:
是的,它也造成了问题,然后我删除了这个 pop() 行,它很好。以上是关于我正在使用 firebase flutter 实现电话身份验证。但是有一个问题的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Flutter 和 Firebase 实时数据库实现邀请系统 [关闭]
使用 Flutter 的电子邮件进行 Firebase 身份验证
使用提供程序在 Flutter 中进行 Firebase 电话身份验证 [关闭]