flutter - Firebase Flutter Web 身份验证持久性
问题描述
Firebase Auth 甚至没有坚持应用重新加载,我已经经历了许多 stackoverflow 的答案,但仍然无法弄清楚代码中的问题。以下是我的颤振代码,
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SplashScreen();
}
}
class SplashScreen extends StatefulWidget {
static final route = '/';
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
Widget build(BuildContext context) {
return StreamBuilder<User>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
User user = snapshot.data;
return MaterialApp(home: (user == null) ? LoginPage() : HomePage());
} else {
return Container(
color: Colors.blueAccent,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'images/dove.png',
height: 150,
width: 150,
),
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 32.0, 8.0, 60.0),
child: Text(
'Loading Pls Wait...',
style: TextStyle(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.bold),
),
)
],
),
),
);
}
},
);
}
@override
void initState() {
super.initState();
}
}
每次我重新加载应用程序或运行应用程序时,它只会导航到登录屏幕,但是在登录屏幕中,当我使用电话号码登录时,它会导航到 MainPage,而无需在登录页面上编写任何代码,即 authstate 更改是在主屏幕中正确收听。以下是登录屏幕页面,
class LoginPage extends StatefulWidget {
static final route = '/Login_Page';
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
@override
Widget build(BuildContext context) {
var media = MediaQuery.of(context).size;
final isSmall = ResponsiveWidget.isSmallScreen(context);
return Scaffold(
appBar: AppBar(
title: Center(child: Text('LogIn')),
),
body: Container(
color: Colors.blue,
child: Row(
children: [
(isSmall)
? Container()
: Padding(
padding: const EdgeInsets.all(100.0),
child: Container(),
),
Expanded(child: LogInInput())
],
),
),
);
}
}
class LogInInput extends StatefulWidget {
@override
_LogInInputState createState() => _LogInInputState();
}
class _LogInInputState extends State<LogInInput> {
final phnoController = TextEditingController(text: '+91');
final _formKey = GlobalKey<FormState>();
final _formKeyOTP = GlobalKey<FormState>();
var codeSent = false;
var onProcess = false;
final otpController = TextEditingController();
ConfirmationResult confirmationResult;
@override
Widget build(BuildContext context) {
final isSmall = ResponsiveWidget.isSmallScreen(context);
return Center(
child: Padding(
padding:
EdgeInsets.fromLTRB(isSmall ? 10 : 50, 0, isSmall ? 10 : 50, 10),
child: Card(
color: Colors.white,
elevation: 5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
child: Wrap(
children: [
Padding(
padding: EdgeInsets.fromLTRB(isSmall ? 10 : 20,
(isSmall) ? 10 : 20, (isSmall) ? 10 : 20, 10),
child: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Icon(
Icons.phone_android,
size: 20,
),
SizedBox(height: 10),
Text(
'Welcome...',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 24),
),
SizedBox(
height: 10,
width: 0,
),
Text(
(!codeSent)
? 'Enter your mobile number to continue'
: 'Enter 6 Digit Code sent to your mobile number',
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(
height: 30,
),
(!codeSent)
? Container(
width: 250,
child: Form(
key: _formKey,
child: TextFormField(
controller: phnoController,
keyboardType: TextInputType.numberWithOptions(
signed: true),
maxLines: 1,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp('[0-9+.,]+')),
],
validator: (text) {
if (text.isEmpty) {
return 'Should not be empty';
}
if (!text.startsWith("+")) {
return 'Enter your country code.eg. + 91';
}
return null;
},
decoration: InputDecoration(
labelText:
'Phone Number with country code'),
),
),
)
: Container(
width: 150,
child: Form(
key: _formKeyOTP,
child: TextFormField(
controller: otpController,
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly
],
validator: (text) {
if (text.isEmpty) {
return 'Should not be empty';
}
if (text.length != 6) {
return 'OTP should be 6 Digits length';
}
return null;
},
decoration: InputDecoration(
labelText: 'Enter 6 digit OTP')),
),
),
SizedBox(
height: 10,
),
MaterialButton(
child: Text((!codeSent) ? 'Send OTP' : 'Verify OTP'),
color: Colors.blue,
onPressed: () {
if (onProcess) {
return;
}
if (!codeSent) {
if (_formKey.currentState.validate()) {
_singIN(phnoController.text);
}
} else {
if (_formKeyOTP.currentState.validate()) {
_verifyOTP(otpController.text);
}
}
},
),
SizedBox(
height: 10,
),
(codeSent)
? MaterialButton(
child: Text('Resend OTP'),
color: Colors.lightBlue,
onPressed: () {
if (onProcess) {
return;
}
_singIN(phnoController.text);
},
)
: Container(),
],
)),
),
),
],
),
),
),
);
}
void _singIN(String text) async {
setState(() {
onProcess = true;
});
FirebaseAuth auth = FirebaseAuth.instance;
await auth.setPersistence(Persistence.LOCAL);
try {
confirmationResult = await auth.signInWithPhoneNumber(text);
} on FirebaseAuthException catch (exception) {
makeAlert(context, exception.message);
setState(() {
onProcess = false;
});
return;
}
setState(() {
codeSent = true;
onProcess = false;
});
}
void _verifyOTP(String text) async {
UserCredential result;
try {
result = await confirmationResult.confirm(text);
} on FirebaseAuthException catch (exception) {
makeAlert(context, exception.message);
setState(() {
onProcess = false;
});
return;
}
}
void makeAlert(BuildContext context, String message) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Error'),
content: Text(message),
));
}
}
以下是我的 pubspec.yaml
dependencies:
flutter:
sdk: flutter
firebase_core: ^0.5.3
firebase_auth: ^0.18.4+1
firebase_db_web_unofficial: ^0.0.2
firebase_storage: ^5.2.0
provider:
我已经在 Edge 和 Google Chrome 中检查过这种行为,两者的行为是相同的。
有人可以帮忙吗?
解决方案
推荐阅读
- c# - 我在将信息从数据库获取到视图中的图表时遇到问题
- python - 自定义 ID Flask Sql Alchemy
- data-visualization - 组合多个 ListDensityPlot3D 的颜色通道
- angular - Ionic Project 中缺少 app.routing.module.ts 文件
- elasticsearch - 如何在匹配中使用 AND 运算符(Kibana 开发工具)
- linux - 从命令行连接文件的内容
- java - @CommandHandler 注释方法中的 Axon 夹具注入失败,构造函数除外
- javascript - 反应子/父组件 - onChange 事件只需要一个字符而不保留值
- javascript - javascript的SweetAlert自动关闭,无需点击弹出窗口
- java - 如何降低 O(n^3) 的复杂性?(提供代码)