firebase - 用户在 Flutter Firebase 身份验证中没有被记住
问题描述
所以每次我的手机或模拟器上的应用程序进程被杀死时,我的应用程序中的用户会自动进入 LoginPage 并且必须重新登录.. 每次重新启动应用程序时登录都非常耗时。Firebase 文档说,用户会被记住,但在我的情况下,它不会......
主要.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:learnon/screens/about.dart';
import 'package:learnon/screens/schwarzesbrett.dart';
import 'package:provider/provider.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:feedback/feedback.dart';
import 'package:shared_preferences/shared_preferences.dart';
import "./screens/selectionpage.dart";
import './screens/product_detail.dart';
import './providers/products.dart';
import '../screens/settings.dart';
import "../screens/essensplan.dart";
import '../screens/vertretungsplan.dart';
import '../screens/startscreen.dart';
import '../widgets/configtheme.dart';
import '../screens/auth_screen.dart';
import '../screens/reset.dart';
import '../screens/lehrerkürzel.dart';
const AndroidNotificationChannel channel = AndroidNotificationChannel(
"high_importance_channel", "High Importance Notifications",
importance: Importance.high, playSound: true);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await Hive.initFlutter();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (ctx) => Products(),
child: MaterialApp(
title: 'LearnOn',
debugShowCheckedModeBanner: false,
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
themeMode: currentTheme.currentTheme(),
home: LoginScreen(),
routes: {
ProductDetail.routeName: (ctx) => ProductDetail(),
Settings.routeName: (ctx) => Settings(),
WebViewContainer.routeName: (ctx) => WebViewContainer(),
Essensplan.routeName: (ctx) => Essensplan(),
StartScreen.routeName: (ctx) => StartScreen(),
ForgotPassword.id: (context) => ForgotPassword(),
SchwarzesBrett.routeName: (ctx) => SchwarzesBrett(),
About.routeName: (ctx) => About(),
Lehrerkuerzel.routeName: (ctx) => Lehrerkuerzel(),
}),
);
}
}
auth_screen.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:learnon/screens/bugstatus.dart';
import 'package:learnon/screens/startscreen.dart';
import '../screens/reset.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({Key? key}) : super(key: key);
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
// form key
final _formKey = GlobalKey<FormState>();
// editing controller
final TextEditingController emailController = new TextEditingController();
final TextEditingController passwordController = new TextEditingController();
//create box1
late Box box1;
@override
void initState() {
super.initState();
createBox();
}
void createBox() async {
box1 = await Hive.openBox("logindata");
getdata();
}
void getdata() async {
if (box1.get("emailController") != null) {
emailController.text = box1.get("emailController");
}
if (box1.get("passwordController") != null) {
passwordController.text = box1.get("passwordController");
}
}
// firebase
final _auth = FirebaseAuth.instance;
//storage key
final storage = new FlutterSecureStorage();
// string for displaying the error Message
String? errorMessage;
@override
Widget build(BuildContext context) {
//email field
final emailField = TextFormField(
autofocus: false,
controller: emailController,
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value!.isEmpty) {
return ("Bitte Email-Adresse eingeben");
}
// reg expression for email validation
if (!RegExp("^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+.[a-z]")
.hasMatch(value)) {
return ("Bitte gültige Email-Adresse eingeben");
}
return null;
},
onSaved: (value) {
emailController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.mail),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Email",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
));
//material buttons
//password field
final passwordField = TextFormField(
autofocus: false,
controller: passwordController,
obscureText: true,
validator: (value) {
RegExp regex = new RegExp(r'^.{6,}$');
if (value!.isEmpty) {
return ("Bitte Passwort eingeben");
}
if (!regex.hasMatch(value)) {
return ("Bitte korrektes Passwort eingeben(Min. 6 Zeichen)");
}
},
onSaved: (value) {
passwordController.text = value!;
},
textInputAction: TextInputAction.done,
decoration: InputDecoration(
prefixIcon: Icon(Icons.vpn_key),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Passwort",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
));
//forget password
final forgetPassword = Material(
elevation: 5,
borderRadius: BorderRadius.circular(30),
color: Colors.green,
child: MaterialButton(
padding: EdgeInsets.fromLTRB(20, 15, 20, 15),
minWidth: MediaQuery.of(context).size.width,
onPressed: () {
Navigator.pushNamed(
context,
ForgotPassword.id,
);
},
child: Text(
"Passwort vergessen?",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.bold),
)));
//password remembering
final Stream<User?> firebaseUserChanges =
FirebaseAuth.instance.userChanges();
//login button
final loginButton = Material(
elevation: 5,
borderRadius: BorderRadius.circular(30),
color: Colors.green,
child: MaterialButton(
padding: EdgeInsets.fromLTRB(20, 15, 20, 15),
minWidth: MediaQuery.of(context).size.width,
onPressed: () {
signIn(emailController.text, passwordController.text);
login();
},
child: Text(
"Login",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold),
)),
);
return Scaffold(
body: Center(
child: SingleChildScrollView(
child: Expanded(
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 200,
child: Image.asset(
"assets/images/Sgglogo_sw_white.png",
fit: BoxFit.contain,
)),
SizedBox(height: 45),
emailField,
SizedBox(height: 25),
passwordField,
SizedBox(height: 35),
loginButton,
SizedBox(height: 15),
forgetPassword,
SizedBox(height: 25),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Bugstatus()));
},
child: const Text("Early Access App",
style: TextStyle(
color: Colors.green,
fontWeight: FontWeight.w800,
))),
])
],
),
),
),
),
),
),
);
}
void login() {
box1.put("emailController", emailController.text);
box1.put("passwordController", passwordController.text);
}
// login function
void signIn(String email, String password) async {
if (_formKey.currentState!.validate()) {
try {
await _auth
.signInWithEmailAndPassword(email: email, password: password)
.then((uid) => {
Fluttertoast.showToast(msg: "Login erfolgreich!"),
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => StartScreen())),
});
} on FirebaseAuthException catch (error) {
switch (error.code) {
case "invalid-email":
errorMessage = "Your email address appears to be malformed.";
break;
case "wrong-password":
errorMessage = "Dein Passwort ist falsch.";
break;
case "user-not-found":
errorMessage = "User mit dieser Email existiert nicht!";
break;
case "user-disabled":
errorMessage = "User with this email has been disabled.";
break;
case "too-many-requests":
errorMessage = "Zu viele Anfragen";
break;
case "operation-not-allowed":
errorMessage = "Anmelden ist zurzeit nicht verfügbar";
break;
default:
errorMessage = "Ein nicht definierter Fehler ist aufgetreten!";
}
Fluttertoast.showToast(msg: errorMessage!);
print(error.code);
}
}
}
}
解决方案
推荐阅读
- java - 如何将文本从 recyclerview 适配器更新到其他布局 xml
- javascript - 使用加号 (+) 在 Keyup 功能中不起作用
- delphi - 比较数组中的实数
- rebus - 从命令处理程序中发布的事件
- wordpress - Wordpress 使用 Walker_Nav_Menu 在父 li 的 div 中添加子菜单
- swift - 如何将变量从 secondViewController 传递给 TableViewController 中的 loadData() 函数?
- elasticsearch - 过滤掉弹性搜索结果的查询以避免数据中的重复删除
- visual-studio-code - 随机高 CPU 使用率
- python - 我们可以在生产中使用 chrome 驱动程序来截取 D3charts 的屏幕截图并发送电子邮件吗
- javascript - 如何简化这个 JavaScript 正则表达式?