Flutter:在应用程序关闭并重新打开后让用户保持登录状态
Flutter: Keep user logged in after app closes and reopen
我是初学者,正在寻求帮助。我试图找到答案,但遗憾的是找不到我正在寻找的答案。我正在构建一个应用程序,用户可以在未登录时看到主页和应用程序的其他部分。这部分我正在工作,但只有当我关闭应用程序并重新启动它时,我才需要重新登录。这当然不理想。我试图寻找 SharedPreferences
但我能找到的所有示例都带有整个应用程序的登录功能,我无法弄清楚如何让它在我的应用程序中运行。下面是我到目前为止的代码。感谢所有帮助,并提前感谢大家!
(抱歉发布了这么多代码,但它可能会有所帮助!)
Main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:reboo1/services/firebaseauthservice.dart';
import 'package:reboo1/services/users.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return StreamProvider<User>.value(
value: AuthService().user,
child: MaterialApp(
title: 'Rèboo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home:HomePage(),
),
);
}
}
HomePage.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:reboo1/authenticate/signin.dart';
import 'package:reboo1/authenticate/signout.dart';
import 'package:reboo1/models/drawerlogin.dart';
import 'package:reboo1/models/drawerlogout.dart';
import 'package:reboo1/services/firebaseauthservice.dart';
import 'package:reboo1/services/users.dart';
class DrawerItem {
String title;
IconData icon;
DrawerItem(this.title, this.icon);
}
class HomePage extends StatefulWidget {
final drawerItems = [
new DrawerItem("Rèboo", Icons.home),
new DrawerItem("Inbox", Icons.mail_outline),
new DrawerItem("Profile", Icons.person_outline),
new DrawerItem("Reservations", Icons.event_note),
new DrawerItem("Favorites", Icons.favorite_border),
new DrawerItem("Vouchers", Icons.card_giftcard),
new DrawerItem("Invite Friends", Icons.person_add),
new DrawerItem("Settings", Icons.settings),
new DrawerItem("FAQ", Icons.help_outline),
new DrawerItem("Terms & Conditions", Icons.assignment),
new DrawerItem("Sign out", Icons.exit_to_app),
];
@override
State<StatefulWidget> createState() {
return new HomePageState();
}
}
class HomePageState extends State<HomePage> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
int _selectedDrawerIndex = 0;
var _setIcon = Icons.person;
var drawer;
String uid;
_getDrawerItemWidget(int pos) {
switch (pos) {
case 0:
return new Reboo();
case 1:
return new Inbox();
case 2:
return new Profile();
case 3:
return new Reservations();
case 4:
return new Favorites();
case 5:
return new Vouchers();
case 6:
return new InviteFriends();
case 7:
return new Settings();
case 8:
return new Faq();
case 9:
return new TermsAndConditions();
case 10:
return new SignOut();
default:
return new Text("Error");
}
}
_onSelectItem(int index) {
setState(() => _selectedDrawerIndex = index);
if (_selectedDrawerIndex == 0) {
setState(() => _setIcon = Icons.person);
} else {
setState(() => _setIcon = Icons.arrow_back);
}
Navigator.of(context).pop(); // close the drawer
}
@override
Widget build(BuildContext context) {
var drawerOptions = <Widget>[];
for (var i = 0; i < widget.drawerItems.length; i++) {
var d = widget.drawerItems[i];
drawerOptions.add(new ListTile(
leading: new Icon(
d.icon,
color: Color(0xFF008577),
),
title: new Text(d.title),
selected: i == _selectedDrawerIndex,
onTap: () => _onSelectItem(i),
));
}
final auth = Provider.of<User>(context, listen: false);
if (auth != null) {
drawer = DrawerLogin();
} else {
drawer = DrawerLogout();
}
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
leading: Builder(
builder: (BuildContext context) {
return IconButton(
icon: new Icon(_setIcon),
onPressed: () {
if (_selectedDrawerIndex == 0) {
Scaffold.of(context).openDrawer();
} else {
setState(() => _selectedDrawerIndex = 0);
setState(() => _setIcon = Icons.person);
}
},
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
);
},
),
centerTitle: true,
title: new Text(widget.drawerItems[_selectedDrawerIndex].title),
backgroundColor: Color(0xFF008577),
elevation: 0.0,
actions: <Widget>[
IconButton(
icon: Icon(Icons.menu, color: Colors.white),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Company()),
);
},
)
],
),
drawer: new Drawer(
child: SingleChildScrollView(
child: new Column(
children: <Widget>[drawer, new Column(children: drawerOptions)],
),
),
),
body: _getDrawerItemWidget(_selectedDrawerIndex),
);
}
}
FirebaseAuthService.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:reboo1/services/users.dart';
import 'package:reboo1/services/database.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// create user obj based on FirebaseUser
User _userFromFirebaseUser(FirebaseUser user){
return user != null ? User(uid: user.uid) : null;
}
// auth change user stream
Stream<User> get user {
return _auth.onAuthStateChanged
.map(_userFromFirebaseUser);
}
// sign with email & password
Future signInWithEmailAndPassword(String email, String password) async {
try {
AuthResult result = await _auth.signInWithEmailAndPassword(email: email, password: password);
FirebaseUser user = result.user;
return _userFromFirebaseUser(user);
}catch(e){
print(e.toString());
return null;
}
}
// register with email & password
Future registerForm(String email, String password, String birthday, String address, String fullName, String phone) async {
try {
AuthResult result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
FirebaseUser user = result.user;
// creat a new document in the database for the user with the uid
await DatabaseService(uid: user.uid).updateUserData(email, birthday, address, fullName, phone);
return _userFromFirebaseUser(user);
}catch(e){
print(e.toString());
return null;
}
}
Stream<String> get onAuthStateChanged =>
_auth.onAuthStateChanged.map(
(FirebaseUser user) => user?.uid,
);
// GET UID
Future<String> getCurrentUID() async {
return (await _auth.currentUser()).uid;
}
Future getCurrentUser() async {
return await _auth.currentUser();
}
//sign out
Future signOut() async{
try{
return await _auth.signOut();
}catch(e){
print(e.toString());
return null;
}
}
}
SignIn.dart
import 'package:flutter/material.dart';
import 'package:reboo1/authenticate/register.dart';
import 'package:reboo1/home/homepage.dart';
import 'package:reboo1/services/constants.dart';
import 'package:reboo1/services/loading.dart';
import 'package:reboo1/services/firebaseauthservice.dart';
import 'package:shared_preferences/shared_preferences.dart';
class SignIn extends StatefulWidget {
final Function toggleView;
SignIn({this.toggleView});
@override
_SignInState createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
final AuthService _auth = AuthService();
final _formKey = GlobalKey<FormState>(); //global key
bool loading = false;
// text field state
String email = '';
String password = '';
String error = '';
@override
Widget build(BuildContext context) {
return loading
? Loading()
: Scaffold(
backgroundColor: Colors.brown[50],
appBar: AppBar(
backgroundColor: Color(0xFF008577),
elevation: 0.0,
title: Text('Sign in to Rèboo'),
actions: <Widget>[
FlatButton.icon(
textColor: Colors.white,
icon: Icon(Icons.person),
label: Text('Register'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Register()),
);
},
)
],
),
body: Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 50.0),
child: Form(
key: _formKey, //global key
child: Column(children: <Widget>[
SizedBox(height: 20.0),
TextFormField(
decoration: textInputDecoration.copyWith(
hintText: 'Email address'),
validator: (val) =>
val.isEmpty ? 'Enter an email address' : null,
onChanged: (val) {
setState(() => email = val);
}),
SizedBox(height: 20.0),
TextFormField(
decoration:
textInputDecoration.copyWith(hintText: 'Password'),
validator: (val) =>
val.length < 8 ? 'Enter valid password' : null,
obscureText: true,
onChanged: (val) {
setState(() => password = val);
},
),
SizedBox(height: 20.0),
RaisedButton(
color: Colors.purple[400],
child:
Text('Sign in', style: TextStyle(color: Colors.white)),
onPressed: () async {
if (_formKey.currentState.validate()) {
setState(() => loading = true);
dynamic result = await _auth.signInWithEmailAndPassword(
email, password);
if (result == null) {
setState(() {
error =
'Could not sign in with those credentials. Please register an account.';
setState(() => loading = false);
});
} else {
setState(() => loading = false);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
}
}
},
),
SizedBox(height: 12.0),
Text(
error,
style: TextStyle(color: Colors.red, fontSize: 14.0),
)
]),
),
),
);
}
}
您可以将某种数据保存到共享首选项中,然后当用户打开应用程序时,您可以从共享首选项中检索该数据以确定用户是否应该已经登录。例如,该数据可以是用户不记名令牌和到期日期。这可能看起来像这样:
将数据保存到共享首选项:
Future storeTokenPropertiesToPreferences(
TokenProperties accessTokenProperties, refreshTokenProperties) async {
final preferences = await SharedPreferences.getInstance();
preferences.setString(
_preferencesLocation,
json.encode(
{
'accessToken': accessTokenProperties?.value,
'refreshToken': refreshTokenProperties?.value,
'accessTokenExpiresAt':
accessTokenProperties?.expiresAt?.toIso8601String(),
'refreshTokenExpiresAt':
refreshTokenProperties?.expiresAt?.toIso8601String(),
},
),
);
检索数据:
Future<TokenProperties> _tokenPropertiesFromPreferences(
String tokenName) async {
final _userData = await _getPreferences();
try {
final value = _userData[tokenName];
final expiresAt = DateTime.parse(_userData['${tokenName}ExpiresAt']);
final lifeTime = expiresAt.difference(DateTime.now()).inSeconds;
return (value == null || expiresAt == null)
? null
: TokenProperties(value, lifeTime);
} catch (e) {
await _loggingService.log(LoggingMethod.ERROR,
'Could not get token properties from preferences for token $tokenName. Got exception: $e');
return null;
}
Future<Map<String, Object>> _getPreferences() async {
final preferences = await SharedPreferences.getInstance();
if (!preferences.containsKey(_preferencesLocation)) return null;
return json.decode(preferences.getString(_preferencesLocation))
as Map<String, Object>;
}
您显然可以将对象属性更改为您需要的任何内容,这只是一个示例。
我不认为你需要搞乱本地存储来保存用户的 detail.As Firebase 本身将用户的详细信息存储在本地 storage.You 只需要调用 FirebaseAuth 的 .currentUser() 方法 class 在您的应用程序启动时对象。如果当前用户为空,则加载登录页面,否则加载您的主页。就这样;
Future loadUser() async {
FirebaseUser _tempUser = await _auth.currentUser();
if (_tempUser != null)
// goto MainPage(mainUser:_tempUser);
} else
// goto LoginPage;
}
提供了一个虚拟实现,但这是解决这个问题的合法方法。如果您想在 google 上搜索,请搜索关键字 firebase onAuthChanged,然后阅读相关信息。无需本地存储,以最简单、最安全的方式处理您的需求。
StreamBuilder<FirebaseUser>(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return print("getting data");
} else if (snapshot.connectionState == ConnectionState.active &&
!snapshot.hasData) {
return print("no user found");
} else if (snapshot.connectionState == ConnectionState.active &&
snapshot.hasData)
{
return print(snapshot.data.currentuser);
}
else
return null;
},
感谢@UTKARSH Sharma,我发现用户没有注销,但问题出在我自己的代码中。我发现以下代码帮助我解决了问题:
@override
void initState() {
super.initState();
var auth = FirebaseAuth.instance;
auth.onAuthStateChanged.listen((user) {
if (user != null) {
print("user is logged in");
//navigate to home page using Navigator Widget
} else {
print("user is not logged in");
//navigate to sign in page using Navigator Widget
}
});
}
谢谢大家的帮助!
我是初学者,正在寻求帮助。我试图找到答案,但遗憾的是找不到我正在寻找的答案。我正在构建一个应用程序,用户可以在未登录时看到主页和应用程序的其他部分。这部分我正在工作,但只有当我关闭应用程序并重新启动它时,我才需要重新登录。这当然不理想。我试图寻找 SharedPreferences
但我能找到的所有示例都带有整个应用程序的登录功能,我无法弄清楚如何让它在我的应用程序中运行。下面是我到目前为止的代码。感谢所有帮助,并提前感谢大家!
(抱歉发布了这么多代码,但它可能会有所帮助!)
Main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:reboo1/services/firebaseauthservice.dart';
import 'package:reboo1/services/users.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return StreamProvider<User>.value(
value: AuthService().user,
child: MaterialApp(
title: 'Rèboo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home:HomePage(),
),
);
}
}
HomePage.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:reboo1/authenticate/signin.dart';
import 'package:reboo1/authenticate/signout.dart';
import 'package:reboo1/models/drawerlogin.dart';
import 'package:reboo1/models/drawerlogout.dart';
import 'package:reboo1/services/firebaseauthservice.dart';
import 'package:reboo1/services/users.dart';
class DrawerItem {
String title;
IconData icon;
DrawerItem(this.title, this.icon);
}
class HomePage extends StatefulWidget {
final drawerItems = [
new DrawerItem("Rèboo", Icons.home),
new DrawerItem("Inbox", Icons.mail_outline),
new DrawerItem("Profile", Icons.person_outline),
new DrawerItem("Reservations", Icons.event_note),
new DrawerItem("Favorites", Icons.favorite_border),
new DrawerItem("Vouchers", Icons.card_giftcard),
new DrawerItem("Invite Friends", Icons.person_add),
new DrawerItem("Settings", Icons.settings),
new DrawerItem("FAQ", Icons.help_outline),
new DrawerItem("Terms & Conditions", Icons.assignment),
new DrawerItem("Sign out", Icons.exit_to_app),
];
@override
State<StatefulWidget> createState() {
return new HomePageState();
}
}
class HomePageState extends State<HomePage> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
int _selectedDrawerIndex = 0;
var _setIcon = Icons.person;
var drawer;
String uid;
_getDrawerItemWidget(int pos) {
switch (pos) {
case 0:
return new Reboo();
case 1:
return new Inbox();
case 2:
return new Profile();
case 3:
return new Reservations();
case 4:
return new Favorites();
case 5:
return new Vouchers();
case 6:
return new InviteFriends();
case 7:
return new Settings();
case 8:
return new Faq();
case 9:
return new TermsAndConditions();
case 10:
return new SignOut();
default:
return new Text("Error");
}
}
_onSelectItem(int index) {
setState(() => _selectedDrawerIndex = index);
if (_selectedDrawerIndex == 0) {
setState(() => _setIcon = Icons.person);
} else {
setState(() => _setIcon = Icons.arrow_back);
}
Navigator.of(context).pop(); // close the drawer
}
@override
Widget build(BuildContext context) {
var drawerOptions = <Widget>[];
for (var i = 0; i < widget.drawerItems.length; i++) {
var d = widget.drawerItems[i];
drawerOptions.add(new ListTile(
leading: new Icon(
d.icon,
color: Color(0xFF008577),
),
title: new Text(d.title),
selected: i == _selectedDrawerIndex,
onTap: () => _onSelectItem(i),
));
}
final auth = Provider.of<User>(context, listen: false);
if (auth != null) {
drawer = DrawerLogin();
} else {
drawer = DrawerLogout();
}
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
leading: Builder(
builder: (BuildContext context) {
return IconButton(
icon: new Icon(_setIcon),
onPressed: () {
if (_selectedDrawerIndex == 0) {
Scaffold.of(context).openDrawer();
} else {
setState(() => _selectedDrawerIndex = 0);
setState(() => _setIcon = Icons.person);
}
},
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
);
},
),
centerTitle: true,
title: new Text(widget.drawerItems[_selectedDrawerIndex].title),
backgroundColor: Color(0xFF008577),
elevation: 0.0,
actions: <Widget>[
IconButton(
icon: Icon(Icons.menu, color: Colors.white),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Company()),
);
},
)
],
),
drawer: new Drawer(
child: SingleChildScrollView(
child: new Column(
children: <Widget>[drawer, new Column(children: drawerOptions)],
),
),
),
body: _getDrawerItemWidget(_selectedDrawerIndex),
);
}
}
FirebaseAuthService.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:reboo1/services/users.dart';
import 'package:reboo1/services/database.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// create user obj based on FirebaseUser
User _userFromFirebaseUser(FirebaseUser user){
return user != null ? User(uid: user.uid) : null;
}
// auth change user stream
Stream<User> get user {
return _auth.onAuthStateChanged
.map(_userFromFirebaseUser);
}
// sign with email & password
Future signInWithEmailAndPassword(String email, String password) async {
try {
AuthResult result = await _auth.signInWithEmailAndPassword(email: email, password: password);
FirebaseUser user = result.user;
return _userFromFirebaseUser(user);
}catch(e){
print(e.toString());
return null;
}
}
// register with email & password
Future registerForm(String email, String password, String birthday, String address, String fullName, String phone) async {
try {
AuthResult result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
FirebaseUser user = result.user;
// creat a new document in the database for the user with the uid
await DatabaseService(uid: user.uid).updateUserData(email, birthday, address, fullName, phone);
return _userFromFirebaseUser(user);
}catch(e){
print(e.toString());
return null;
}
}
Stream<String> get onAuthStateChanged =>
_auth.onAuthStateChanged.map(
(FirebaseUser user) => user?.uid,
);
// GET UID
Future<String> getCurrentUID() async {
return (await _auth.currentUser()).uid;
}
Future getCurrentUser() async {
return await _auth.currentUser();
}
//sign out
Future signOut() async{
try{
return await _auth.signOut();
}catch(e){
print(e.toString());
return null;
}
}
}
SignIn.dart
import 'package:flutter/material.dart';
import 'package:reboo1/authenticate/register.dart';
import 'package:reboo1/home/homepage.dart';
import 'package:reboo1/services/constants.dart';
import 'package:reboo1/services/loading.dart';
import 'package:reboo1/services/firebaseauthservice.dart';
import 'package:shared_preferences/shared_preferences.dart';
class SignIn extends StatefulWidget {
final Function toggleView;
SignIn({this.toggleView});
@override
_SignInState createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
final AuthService _auth = AuthService();
final _formKey = GlobalKey<FormState>(); //global key
bool loading = false;
// text field state
String email = '';
String password = '';
String error = '';
@override
Widget build(BuildContext context) {
return loading
? Loading()
: Scaffold(
backgroundColor: Colors.brown[50],
appBar: AppBar(
backgroundColor: Color(0xFF008577),
elevation: 0.0,
title: Text('Sign in to Rèboo'),
actions: <Widget>[
FlatButton.icon(
textColor: Colors.white,
icon: Icon(Icons.person),
label: Text('Register'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Register()),
);
},
)
],
),
body: Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 50.0),
child: Form(
key: _formKey, //global key
child: Column(children: <Widget>[
SizedBox(height: 20.0),
TextFormField(
decoration: textInputDecoration.copyWith(
hintText: 'Email address'),
validator: (val) =>
val.isEmpty ? 'Enter an email address' : null,
onChanged: (val) {
setState(() => email = val);
}),
SizedBox(height: 20.0),
TextFormField(
decoration:
textInputDecoration.copyWith(hintText: 'Password'),
validator: (val) =>
val.length < 8 ? 'Enter valid password' : null,
obscureText: true,
onChanged: (val) {
setState(() => password = val);
},
),
SizedBox(height: 20.0),
RaisedButton(
color: Colors.purple[400],
child:
Text('Sign in', style: TextStyle(color: Colors.white)),
onPressed: () async {
if (_formKey.currentState.validate()) {
setState(() => loading = true);
dynamic result = await _auth.signInWithEmailAndPassword(
email, password);
if (result == null) {
setState(() {
error =
'Could not sign in with those credentials. Please register an account.';
setState(() => loading = false);
});
} else {
setState(() => loading = false);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
}
}
},
),
SizedBox(height: 12.0),
Text(
error,
style: TextStyle(color: Colors.red, fontSize: 14.0),
)
]),
),
),
);
}
}
您可以将某种数据保存到共享首选项中,然后当用户打开应用程序时,您可以从共享首选项中检索该数据以确定用户是否应该已经登录。例如,该数据可以是用户不记名令牌和到期日期。这可能看起来像这样:
将数据保存到共享首选项:
Future storeTokenPropertiesToPreferences(
TokenProperties accessTokenProperties, refreshTokenProperties) async {
final preferences = await SharedPreferences.getInstance();
preferences.setString(
_preferencesLocation,
json.encode(
{
'accessToken': accessTokenProperties?.value,
'refreshToken': refreshTokenProperties?.value,
'accessTokenExpiresAt':
accessTokenProperties?.expiresAt?.toIso8601String(),
'refreshTokenExpiresAt':
refreshTokenProperties?.expiresAt?.toIso8601String(),
},
),
);
检索数据:
Future<TokenProperties> _tokenPropertiesFromPreferences(
String tokenName) async {
final _userData = await _getPreferences();
try {
final value = _userData[tokenName];
final expiresAt = DateTime.parse(_userData['${tokenName}ExpiresAt']);
final lifeTime = expiresAt.difference(DateTime.now()).inSeconds;
return (value == null || expiresAt == null)
? null
: TokenProperties(value, lifeTime);
} catch (e) {
await _loggingService.log(LoggingMethod.ERROR,
'Could not get token properties from preferences for token $tokenName. Got exception: $e');
return null;
}
Future<Map<String, Object>> _getPreferences() async {
final preferences = await SharedPreferences.getInstance();
if (!preferences.containsKey(_preferencesLocation)) return null;
return json.decode(preferences.getString(_preferencesLocation))
as Map<String, Object>;
}
您显然可以将对象属性更改为您需要的任何内容,这只是一个示例。
我不认为你需要搞乱本地存储来保存用户的 detail.As Firebase 本身将用户的详细信息存储在本地 storage.You 只需要调用 FirebaseAuth 的 .currentUser() 方法 class 在您的应用程序启动时对象。如果当前用户为空,则加载登录页面,否则加载您的主页。就这样;
Future loadUser() async {
FirebaseUser _tempUser = await _auth.currentUser();
if (_tempUser != null)
// goto MainPage(mainUser:_tempUser);
} else
// goto LoginPage;
}
提供了一个虚拟实现,但这是解决这个问题的合法方法。如果您想在 google 上搜索,请搜索关键字 firebase onAuthChanged,然后阅读相关信息。无需本地存储,以最简单、最安全的方式处理您的需求。
StreamBuilder<FirebaseUser>(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return print("getting data");
} else if (snapshot.connectionState == ConnectionState.active &&
!snapshot.hasData) {
return print("no user found");
} else if (snapshot.connectionState == ConnectionState.active &&
snapshot.hasData)
{
return print(snapshot.data.currentuser);
}
else
return null;
},
感谢@UTKARSH Sharma,我发现用户没有注销,但问题出在我自己的代码中。我发现以下代码帮助我解决了问题:
@override
void initState() {
super.initState();
var auth = FirebaseAuth.instance;
auth.onAuthStateChanged.listen((user) {
if (user != null) {
print("user is logged in");
//navigate to home page using Navigator Widget
} else {
print("user is not logged in");
//navigate to sign in page using Navigator Widget
}
});
}
谢谢大家的帮助!