flutter firebase 登录问题
issue with flutter firebase login
我最近在我的应用程序上使用 login/register 模块进行了一些工作,但有 2 个东西不工作:
- 首先,当我注册时没问题,我可以在我的 Firebase 控制台中看到该应用程序正在创建一个新用户,所以这很好。但是,当我尝试使用不存在的用户登录时,它仍然让我转到主页。
- 不知道如何进行持久登录,比如有人登录,有人在关闭应用程序时注册,然后重新启动应用程序,他们应该能够保持登录状态,然后在需要时注销。
有人能帮忙吗??
我把代码留在这里:
主要
import 'package:flutter/material.dart';
import 'package:sport_app/auth_screen.dart';
import 'package:sport_app/home_screen.dart';
import 'package:sport_app/intro_screen.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: Color(0xfff2f9fe),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[200]),
borderRadius: BorderRadius.circular(25),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[200]),
borderRadius: BorderRadius.circular(25),
),
disabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[200]),
borderRadius: BorderRadius.circular(25),
),
),
),
home: IntroScreen(),
routes: {
'intro': (context) => IntroScreen(),
'home': (context) => HomeScreen(),
'login': (context) => AuthScreen(authType: AuthType.login),
'register': (context) => AuthScreen(authType: AuthType.register),
},
);
}
}
AUTH_PAGE
import 'package:flutter/material.dart';
import 'package:sport_app/auth_screen.dart';
import 'package:sport_app/auth.dart';
import 'package:sport_app/original_button.dart';
class AuthForm extends StatefulWidget {
final AuthType authType;
const AuthForm({Key key, @required this.authType}) : super(key: key);
@override
_AuthFormState createState() => _AuthFormState();
}
class _AuthFormState extends State<AuthForm> {
final _formKey = GlobalKey<FormState>();
String _email = '', _password = '';
AuthBase authBase = AuthBase();
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 20),
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'Enter your email',
hintText: 'ex: test@gmail.com',
),
onChanged: (value) {
_email = value;
},
validator: (value) =>
value.isEmpty ? 'You must enter a valid email' : null,
),
SizedBox(height: 10),
TextFormField(
decoration: InputDecoration(
labelText: 'Enter your password',
),
obscureText: true,
onChanged: (value) {
_password = value;
},
validator: (value) => value.length <= 6
? 'Your password must be larger than 6 characters'
: null,
),
SizedBox(height: 20),
OriginalButton(
text: widget.authType == AuthType.login ? 'Login' : 'Register',
color: Colors.lightBlue,
textColor: Colors.white,
onPressed: () async {
if (_formKey.currentState.validate()) {
if (widget.authType == AuthType.login) {
await authBase.loginWithEmailAndPassword(_email, _password);
Navigator.of(context).pushReplacementNamed('home');
} else {
await authBase.registerWithEmailAndPassword(_email, _password);
Navigator.of(context).pushReplacementNamed('home');
}
// print(_email);
// print(_password);
}
},
),
SizedBox(height: 6),
FlatButton(
onPressed: () {
if (widget.authType == AuthType.login) {
Navigator.of(context).pushReplacementNamed('register');
print(widget.authType);
} else {
Navigator.of(context).pushReplacementNamed('login');
}
},
child: Text(
widget.authType == AuthType.login
? 'Don\'t have an account?'
: 'Already have an account?',
style: TextStyle(fontSize: 18, color: Colors.black54),
),
),
],
),
),
);
}
}
AUTHBASE
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
class User {
final String uid;
User({@required this.uid});
}
class AuthBase {
User _userFromFirebase(FirebaseUser user) {
return user != null ? User(uid: user.uid) : null;
}
Future<void> registerWithEmailAndPassword(
String email, String password) async {
try {
final authResult = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
return _userFromFirebase(authResult.user);
} catch (e) {
print(e.toString());
return null;
}
}
Future<void> loginWithEmailAndPassword(String email, String password) async {
try {
final authResult = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
return _userFromFirebase(authResult.user);
} catch (e) {
print(e.toString());
return null;
}
}
Future<void> logout() async {
await FirebaseAuth.instance.signOut();
}
}
更新
您只需导航至主页,即使登录未成功完成,因为没有条件逻辑。仅在您的 authBase class 中进行导航,那么您应该没问题。
您需要导入 FirebaseAuthException 才能使用它。那么,你
Future<bool> loginWithEmailAndPassword(String email, String password) async {
try {
final authResult = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
if(authResult.user != null) { Navigator.of(context).pushReplacementNamed('home'); }
} on FirebaseAuthException catch (e) {
print(e.toString());
if(e.code == 'wrong-password') { Scaffold.of(context).showSnackBar(SnackBar(
content: Text("Wrong Password"),
)); }
else if (e.code == 'user-not-found') { Scaffold.of(context).showSnackBar(SnackBar(
content: Text("User not found"),
)); }
else if (e.code == 'invalid-email') { Scaffold.of(context).showSnackBar(SnackBar(
content: Text("Invalid E-Mail"),
)); }
return false;
}
}
并删除将您的小部件代码更改为:
if (_formKey.currentState.validate()) {
if (widget.authType == AuthType.login) {
await authBase.loginWithEmailAndPassword(_email, _password);
} else {
await authBase.registerWithEmailAndPassword(_email, _password);
}
}
第二个问题:
您可以尝试在第一次登录后将登录凭据存储在存储(用户flutter_secure_storage 加密包)中,然后在应用程序启动时检索它以执行上述登录
这是一个 link 用于存储凭据的包
我最近在我的应用程序上使用 login/register 模块进行了一些工作,但有 2 个东西不工作:
- 首先,当我注册时没问题,我可以在我的 Firebase 控制台中看到该应用程序正在创建一个新用户,所以这很好。但是,当我尝试使用不存在的用户登录时,它仍然让我转到主页。
- 不知道如何进行持久登录,比如有人登录,有人在关闭应用程序时注册,然后重新启动应用程序,他们应该能够保持登录状态,然后在需要时注销。
有人能帮忙吗??
我把代码留在这里:
主要
import 'package:flutter/material.dart';
import 'package:sport_app/auth_screen.dart';
import 'package:sport_app/home_screen.dart';
import 'package:sport_app/intro_screen.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: Color(0xfff2f9fe),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[200]),
borderRadius: BorderRadius.circular(25),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[200]),
borderRadius: BorderRadius.circular(25),
),
disabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[200]),
borderRadius: BorderRadius.circular(25),
),
),
),
home: IntroScreen(),
routes: {
'intro': (context) => IntroScreen(),
'home': (context) => HomeScreen(),
'login': (context) => AuthScreen(authType: AuthType.login),
'register': (context) => AuthScreen(authType: AuthType.register),
},
);
}
}
AUTH_PAGE
import 'package:flutter/material.dart';
import 'package:sport_app/auth_screen.dart';
import 'package:sport_app/auth.dart';
import 'package:sport_app/original_button.dart';
class AuthForm extends StatefulWidget {
final AuthType authType;
const AuthForm({Key key, @required this.authType}) : super(key: key);
@override
_AuthFormState createState() => _AuthFormState();
}
class _AuthFormState extends State<AuthForm> {
final _formKey = GlobalKey<FormState>();
String _email = '', _password = '';
AuthBase authBase = AuthBase();
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 20),
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'Enter your email',
hintText: 'ex: test@gmail.com',
),
onChanged: (value) {
_email = value;
},
validator: (value) =>
value.isEmpty ? 'You must enter a valid email' : null,
),
SizedBox(height: 10),
TextFormField(
decoration: InputDecoration(
labelText: 'Enter your password',
),
obscureText: true,
onChanged: (value) {
_password = value;
},
validator: (value) => value.length <= 6
? 'Your password must be larger than 6 characters'
: null,
),
SizedBox(height: 20),
OriginalButton(
text: widget.authType == AuthType.login ? 'Login' : 'Register',
color: Colors.lightBlue,
textColor: Colors.white,
onPressed: () async {
if (_formKey.currentState.validate()) {
if (widget.authType == AuthType.login) {
await authBase.loginWithEmailAndPassword(_email, _password);
Navigator.of(context).pushReplacementNamed('home');
} else {
await authBase.registerWithEmailAndPassword(_email, _password);
Navigator.of(context).pushReplacementNamed('home');
}
// print(_email);
// print(_password);
}
},
),
SizedBox(height: 6),
FlatButton(
onPressed: () {
if (widget.authType == AuthType.login) {
Navigator.of(context).pushReplacementNamed('register');
print(widget.authType);
} else {
Navigator.of(context).pushReplacementNamed('login');
}
},
child: Text(
widget.authType == AuthType.login
? 'Don\'t have an account?'
: 'Already have an account?',
style: TextStyle(fontSize: 18, color: Colors.black54),
),
),
],
),
),
);
}
}
AUTHBASE
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
class User {
final String uid;
User({@required this.uid});
}
class AuthBase {
User _userFromFirebase(FirebaseUser user) {
return user != null ? User(uid: user.uid) : null;
}
Future<void> registerWithEmailAndPassword(
String email, String password) async {
try {
final authResult = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
return _userFromFirebase(authResult.user);
} catch (e) {
print(e.toString());
return null;
}
}
Future<void> loginWithEmailAndPassword(String email, String password) async {
try {
final authResult = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
return _userFromFirebase(authResult.user);
} catch (e) {
print(e.toString());
return null;
}
}
Future<void> logout() async {
await FirebaseAuth.instance.signOut();
}
}
更新
您只需导航至主页,即使登录未成功完成,因为没有条件逻辑。仅在您的 authBase class 中进行导航,那么您应该没问题。
您需要导入 FirebaseAuthException 才能使用它。那么,你
Future<bool> loginWithEmailAndPassword(String email, String password) async {
try {
final authResult = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
if(authResult.user != null) { Navigator.of(context).pushReplacementNamed('home'); }
} on FirebaseAuthException catch (e) {
print(e.toString());
if(e.code == 'wrong-password') { Scaffold.of(context).showSnackBar(SnackBar(
content: Text("Wrong Password"),
)); }
else if (e.code == 'user-not-found') { Scaffold.of(context).showSnackBar(SnackBar(
content: Text("User not found"),
)); }
else if (e.code == 'invalid-email') { Scaffold.of(context).showSnackBar(SnackBar(
content: Text("Invalid E-Mail"),
)); }
return false;
}
}
并删除将您的小部件代码更改为:
if (_formKey.currentState.validate()) {
if (widget.authType == AuthType.login) {
await authBase.loginWithEmailAndPassword(_email, _password);
} else {
await authBase.registerWithEmailAndPassword(_email, _password);
}
}
第二个问题: 您可以尝试在第一次登录后将登录凭据存储在存储(用户flutter_secure_storage 加密包)中,然后在应用程序启动时检索它以执行上述登录
这是一个 link 用于存储凭据的包