“我正在创建一个基于角色的Flutter应用程序,其中的角色是病人,远程护理,顾问和管理员。我已经创建了登录页面,每个人都能够正确登录,但当您关闭应用程序并返回时,它不会保持用户登录,而是将您发送回登录屏幕,我如何解决这个问题?
这是我所尝试的;
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:telenursingapp/admin_portal.dart';
import 'package:telenursingapp/consultant_portal.dart';
import 'package:telenursingapp/patients_portal.dart';
import 'package:telenursingapp/telenurse_portal.dart';
class SignIn extends StatefulWidget {
const SignIn({super.key});
@override
State<SignIn> createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
// text controllers
bool _isObscure3 = true;
bool visible = false;
final _formkey = GlobalKey<FormState>();
final TextEditingController emailController = new TextEditingController();
final TextEditingController passwordController = new TextEditingController();
final _auth = FirebaseAuth.instance;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [Colors.blueGrey, Color(0xFF3EB489)]),
),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 1.0,
child: Center(
child: Container(
margin: EdgeInsets.all(12),
child: Form(
key: _formkey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 30,
),
Image.asset('assets/YourDoc-black.png', width: 70),
Icon(
FontAwesomeIcons.solidHandshake,
size: 20,
color: Colors.black,
),
SizedBox(height: 80,),
Text('Login to your account!',
style: TextStyle(
color: Colors.white,
fontSize: 44,
fontWeight: FontWeight.bold
)),
const SizedBox(height: 10,),
const Text('Welcome back to YourDoc',
style: TextStyle(
color: Color.fromARGB(255, 88, 85, 85),
fontSize: 24,)),
SizedBox(
height: 20,
),
TextFormField(
controller: emailController,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
hintText: 'Email',
enabled: true,
contentPadding: const EdgeInsets.only(
left: 14.0, bottom: 8.0, top: 8.0),
focusedBorder: OutlineInputBorder(
borderSide: new BorderSide(color: Colors.white),
borderRadius: new BorderRadius.circular(10),
),
enabledBorder: UnderlineInputBorder(
borderSide: new BorderSide(color: Colors.white),
borderRadius: new BorderRadius.circular(10),
),
),
validator: (value) {
if (value!.length == 0) {
return "Email cannot be empty";
}
if (!RegExp(
"^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+.[a-z]")
.hasMatch(value)) {
return ("Please enter a valid email");
} else {
return null;
}
},
onSaved: (value) {
emailController.text = value!;
},
keyboardType: TextInputType.emailAddress,
),
SizedBox(
height: 20,
),
TextFormField(
controller: passwordController,
obscureText: _isObscure3,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(_isObscure3
? Icons.visibility
: Icons.visibility_off),
onPressed: () {
setState(() {
_isObscure3 = !_isObscure3;
});
}),
filled: true,
fillColor: Colors.white,
hintText: 'Password',
enabled: true,
contentPadding: const EdgeInsets.only(
left: 14.0, bottom: 8.0, top: 15.0),
focusedBorder: OutlineInputBorder(
borderSide: new BorderSide(color: Colors.white),
borderRadius: new BorderRadius.circular(10),
),
enabledBorder: UnderlineInputBorder(
borderSide: new BorderSide(color: Colors.white),
borderRadius: new BorderRadius.circular(10),
),
),
validator: (value) {
RegExp regex = new RegExp(r'^.{6,}$');
if (value!.isEmpty) {
return "Password cannot be empty";
}
if (!regex.hasMatch(value)) {
return ("please enter valid password min. 6 character");
} else {
return null;
}
},
onSaved: (value) {
passwordController.text = value!;
},
keyboardType: TextInputType.emailAddress,
),
SizedBox(
height: 20,
),
MaterialButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(20.0))),
elevation: 5.0,
height: 40,
minWidth: 500,
onPressed: () {
setState(() {
visible = true;
});
signIn(
emailController.text, passwordController.text);
},
color: Color.fromARGB(255, 20, 85, 206),
child: Text(
"Login",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
SizedBox(
height: 10,
),
Visibility(
maintainSize: true,
maintainAnimation: true,
maintainState: true,
visible: visible,
child: Container(
child: CircularProgressIndicator(
color: Colors.white,
))),
],
),
),
),
),
),
],
),
),
);
}
void route() {
User? user = FirebaseAuth.instance.currentUser;
var kk = FirebaseFirestore.instance
.collection('users')
.doc(user!.uid)
.get()
.then((DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists) {
if (documentSnapshot.get('role') == "Patient") {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => PatientsPortal(),
),
);
}
else if(documentSnapshot.get('role') == "Consultant"){
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => ConsultantPortal()));
}
else if(documentSnapshot.get('role') == "New Admin"){
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => AdminPortal()));
}
else if(documentSnapshot.get('role') == "Telenurse"){
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => TelenursePortal()));
}
else{
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => SignIn(),
),
);
}
} else {
print('Document does not exist on the database');
}
});
}
void signIn(String email, String password) async {
if (_formkey.currentState!.validate()) {
try {
UserCredential userCredential =
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email,
password: password,
);
route();
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
print('No user found for that email.');
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
}
}
}
}
}
2条答案
按热度按时间hgqdbh6s1#
您应该使用或Shared Preferences在本地存储一个名为isLoggedInUser的布尔变量,一旦用户登录,您可以将此变量设置为true,其默认值为false。
因此,发生的事情是,你可以检查启动屏幕,如果该标志是真的,那么你将重定向用户到 Jmeter 板,否则你可以重定向用户到登录屏幕。
您还可以存储其他变量,如用户类型和他们的id,以供在应用程序中进一步使用。这样用户就不需要每次打开应用程序时都登录。
这里有一个类,你可以用它在本地存储和获取变量。
import 'package:shared_preferences/shared_preferences. dart';
这样使用:
集合:
MyPrefs().setValue("isLoggedInUser", true/false);
。<--这里需要传递true或false作为值获取:
await MyPrefs().getValue("isLoggedInUser", false);
。<--这里false是默认值dgenwo3n2#
Firebase Authentication SDK会自动将用户的凭据存储在本地存储中,并在应用重新启动时从本地存储中恢复这些凭据。
然而,这样做需要它调用服务器,检查凭证是否仍然有效,并确保用户没有被禁用,这需要时间。
在此检查期间,应用程序不会等待第一次渲染,而是在此过程中正常启动。这是第一次运行你的
build
和route
,(我猜,因为我在你分享的内容中没有看到这段代码)然后检查FirebaseAuth.instance.currentUser
并注意到它是null
,所以没有人登录(还没有)。没有办法阻止这种行为。因此,您应该通过侦听
authStateChanges()
流来响应Firebase何时完成其恢复流程,如获取当前用户的文档的第一个示例所示:由于您可能会在UI中执行此操作,因此需要在其中使用
StreamBuilder
来 PackageFirebaseAuth.instance.authStateChanges()
。