英文:
How to make a Signout button in Flutter with Firebase authentication?
问题
It looks like you want assistance with an issue related to user authentication in your Flutter app. Specifically, you want to be able to sign out and then authenticate again without needing to restart the app.
The problem you're encountering may be related to the fact that when you sign out and then sign in again, the user data is not updated correctly. To resolve this issue, you can try the following steps:
-
Clear User Data on Sign Out: When you sign out the user, make sure you also clear any cached user data. In your
signOut
function, after callingawait FirebaseAuth.instance.signOut();
, you should also reset any user-related state or data that you have cached. This ensures that when you sign in again, you start with a clean slate. -
Check User Authentication State: In your
MyHomePage
widget, you can check the user's authentication state in thebuild
method to determine whether to show the login button or proceed to the home page. Instead of using a cached value, you can useFirebaseAuth.instance.currentUser
to check if the user is logged in or not. If the user is logged in, navigate to the home page; otherwise, show the login button.
Here's a simplified example of how you can modify your MyHomePage
widget to achieve this:
class MyHomePage extends ConsumerWidget {
// ...
@override
Widget build(BuildContext context, watch) {
final user = FirebaseAuth.instance.currentUser;
return SafeArea(
child: Scaffold(
key: scaffoldState,
body: Container(
// ...
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
padding: const EdgeInsets.all(16),
width: MediaQuery.of(context).size.width,
child: user == null
? ElevatedButton.icon(
onPressed: () => processLogin(context),
icon: Icon(
Icons.phone,
color: Colors.white,
),
label: Text(
'Login with phone',
style: TextStyle(color: Colors.white),
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.black)),
)
: Container(),
),
],
),
),
),
);
}
// ...
}
By checking the user
variable and displaying the login button only when the user is not logged in, you can handle sign-in and sign-out flows without needing to restart the app.
Make sure to update the state management accordingly based on your specific implementation.
英文:
I am trying to add sign out function in my app. This app has phone authentication.
Here's the code of the home screen:
import 'package:carousel_slider/carousel_slider.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:untitled2/model/image_model.dart';
import 'package:untitled2/state/state_management.dart';
import '../cloud_firestore/banner_ref.dart';
import '../cloud_firestore/lookbook_ref.dart';
import '../cloud_firestore/user_ref.dart';
import '../main.dart';
import '../model/user_model.dart';
class HomePage extends ConsumerWidget {
@override
Widget build(BuildContext context, watch) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: Color(0xFFDFDFDF),
body: SingleChildScrollView(
child: Column(children: [
//user profile
FutureBuilder(
future: getUserProfiles(context,
FirebaseAuth.instance.currentUser!.phoneNumber!),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(
child: CircularProgressIndicator(),
);
else {
var userModel = snapshot.data as UserModel;
return Container(
decoration: BoxDecoration(color: Color(0xFF383838)),
padding: const EdgeInsets.all(16),
child: Row(
children: [
CircleAvatar(
child: Icon(
Icons.person,
color: Colors.white,
size: 30,
),
maxRadius: 30,
backgroundColor: Colors.black,
),
SizedBox(
width: 30,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${userModel.name}',
style: GoogleFonts.robotoMono(
fontSize: 22,
color: Colors.white,
fontWeight: FontWeight.bold),
),
Text(
'${userModel.address}',
overflow: TextOverflow.ellipsis,
style: GoogleFonts.robotoMono(
fontSize: 18,
color: Colors.white,
),
)
],
),
),
IconButton(icon: Icon(Icons.logout,
color: Colors.white,),
onPressed: () =>
signOut(context),),
context.read(userInformation).state.isStaff ?
IconButton(icon: Icon(Icons.admin_panel_settings,
color: Colors.white,),
onPressed: () =>
Navigator.of(context).pushNamed(
'/staffHome'),) : Container()
],
),
);
}
}),
//Menu
Padding(
padding: const EdgeInsets.all(4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: GestureDetector(
onTap: () => Navigator.pushNamed(context, '/booking'),
child: Container(
child: Card(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.book_online,
size: 50,
),
Text(
'Booking',
style: GoogleFonts.robotoMono(),
)
],
),
),
),
),
),
),
Expanded(
child: GestureDetector(onTap: () => Navigator.pushNamed(context, '/history'),
child: Container(
child: Card(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.history,
size: 50,
),
Text(
'History',
style: GoogleFonts.robotoMono(),
)
],
),
),
),
),),
)
],
),
),
//Banner
FutureBuilder(
future: getBanners(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(
child: CircularProgressIndicator(),
);
else {
var banners = snapshot.data as List<ImageModel>;
return CarouselSlider(
options: CarouselOptions(
enlargeCenterPage: true,
aspectRatio: 3.0,
autoPlay: true,
autoPlayInterval: Duration(seconds: 3)),
items: banners
.map((e) => Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(e.image),
),
))
.toList());
}
}),
//Lookbook
Padding(
padding: const EdgeInsets.all(8),
child: Row(
children: [
Text(
'Lookbook',
style: GoogleFonts.robotoMono(fontSize: 24),
)
],
),
),
FutureBuilder(
future: getLookbook(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(
child: CircularProgressIndicator(),
);
else if (!snapshot.hasData || snapshot.data == null)
return SizedBox.shrink();
else {
var lookbook = snapshot.data as List<ImageModel>;
return Column(
children: lookbook
.map((e) => Container(
padding: const EdgeInsets.all(8),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(e.image),
),
))
.toList(),
);
}
}),
]),
),
));
}
Future<void> signOut(BuildContext context) async {
Navigator.of(context).pop();
await FirebaseAuth.instance.signOut();
runApp(ProviderScope(
child:
new MaterialApp(
home: new MyHomePage(),
)
)
);
}
}
and this is the main code:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_auth_ui/flutter_auth_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:page_transition/page_transition.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
import 'package:untitled2/screens/booking_screen.dart';
import 'package:untitled2/screens/done_services_screens.dart';
import 'package:untitled2/screens/home_screen.dart';
import 'package:untitled2/screens/staff_home_screen.dart';
import 'package:untitled2/screens/user_history_screen.dart';
import 'package:untitled2/state/state_management.dart';
import 'package:untitled2/utils/utils.dart';
import 'firebase_options.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Barber Booking App',
onGenerateRoute: (settings) {
switch (settings.name) {
case '/staffHome':
return PageTransition(
settings: settings,
child: StaffHome(),
type: PageTransitionType.fade);
break;
case '/doneService':
return PageTransition(
settings: settings,
child: DoneService(),
type: PageTransitionType.fade);
break;
case '/home':
return PageTransition(
settings: settings,
child: HomePage(),
type: PageTransitionType.fade);
break;
case '/history':
return PageTransition(
settings: settings,
child: UserHistory(),
type: PageTransitionType.fade);
break;
case '/booking':
return PageTransition(
settings: settings,
child: BookingScreen(),
type: PageTransitionType.fade);
break;
default:
return null;
}
},
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends ConsumerWidget {
GlobalKey<ScaffoldState> scaffoldState = new GlobalKey();
processLogin(BuildContext context) {
var user = FirebaseAuth.instance.currentUser;
if (user == null) {
FlutterAuthUi.startUi(
items: [AuthUiProvider.phone],
tosAndPrivacyPolicy: TosAndPrivacyPolicy(
tosUrl: 'https://google.com',
privacyPolicyUrl: 'https://google.com'),
androidOption: AndroidOption(
enableSmartLock: false, showLogo: true, overrideTheme: true))
.then((value) async {
//refresh state
context.read(userLogged).state = FirebaseAuth.instance.currentUser;
//start new screen
await checkLoginState(context, true, scaffoldState);
}).catchError((e) {
ScaffoldMessenger.of(scaffoldState.currentContext!)
.showSnackBar(SnackBar(content: Text('${e.toString()}')));
});
} else {}
}
@override
Widget build(BuildContext context, watch) {
return SafeArea(
child: Scaffold(
key: scaffoldState,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/my_bg.png'),
fit: BoxFit.cover)),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
padding: const EdgeInsets.all(16),
width: MediaQuery.of(context).size.width,
child: FutureBuilder(
future: checkLoginState(context, false, scaffoldState),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(
child: CircularProgressIndicator(),
);
else {
var userState = snapshot.data as LOGIN_STATE;
print(userState);
if (userState == LOGIN_STATE.LOGGED) {
return Container();
} else {
return ElevatedButton.icon(
onPressed: () => processLogin(context),
icon: Icon(
Icons.phone,
color: Colors.white,
),
label: Text(
'Login with phone',
style: TextStyle(color: Colors.white),
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.black)),
);
}
}
},
),
)
],
),
)));
}
Future<LOGIN_STATE> checkLoginState(BuildContext context, bool fromLogin,
GlobalKey<ScaffoldState> scaffoldState) async {
if (!context.read(forceReload).state) {
await Future.delayed(
Duration(seconds: fromLogin == true ? 0 : 3),
() async {
try {
var token = await FirebaseAuth.instance.currentUser!.getIdToken();
//print('$token');
context.read(userToken).state = token;
CollectionReference userRef =
FirebaseFirestore.instance.collection('User');
DocumentSnapshot snapshotUser = await userRef
.doc(FirebaseAuth.instance.currentUser!.phoneNumber)
.get();
//Force reload state
context.read(forceReload).state = true;
if (snapshotUser.exists) {
Navigator.pushNamedAndRemoveUntil(
context, '/home', (route) => false);
} else {
var nameController = TextEditingController();
var addressController = TextEditingController();
Alert(
context: context,
title: 'Update data',
content: Column(
children: [
TextField(
decoration: InputDecoration(
icon: Icon(Icons.account_circle), labelText: 'Имя'),
controller: nameController,
),
TextField(
decoration: InputDecoration(
icon: Icon(Icons.home), labelText: 'Адрес'),
controller: addressController,
)
],
),
buttons: [
DialogButton(
child: Text('Cancel'),
onPressed: () => Navigator.pop(context),
),
DialogButton(
child: Text('Update'),
onPressed: () {
//update to server
userRef
.doc(FirebaseAuth.instance.currentUser!.phoneNumber)
.set({
'name': nameController.text,
'address': addressController.text
}).then((value) async {
Navigator.pop(context);
ScaffoldMessenger.of(scaffoldState.currentContext!)
.showSnackBar(SnackBar(
content: Text('Update Successful!'),
));
await Future.delayed(Duration(seconds: 1), () {
Navigator.pushNamedAndRemoveUntil(
context, '/home', (route) => false);
});
}).catchError((e) {
Navigator.pop(context);
ScaffoldMessenger.of(scaffoldState.currentContext!)
.showSnackBar(SnackBar(content: Text('$e')));
});
},
),
],
).show();
}
} catch (e) {
print(e);
return null;
}
},
);
}
return FirebaseAuth.instance.currentUser != null
? LOGIN_STATE.LOGGED
: LOGIN_STATE.NOT_LOGIN;
}
}
login depends on this code:
enum LOGIN_STATE { LOGGED, NOT_LOGIN }
App redirects me to the main page, but when I authenticate again, app does not send me to the home page because the user data still be saved.
When I delete this part of code in home screen:
runApp(ProviderScope(
child:
new MaterialApp(
home: new MyHomePage(),
)
)
);
Sign out button works when I restart the app. But I need to autenticate without restarting app. Please help.
答案1
得分: -1
以下是您提供的代码的翻译部分:
主要代码部分:
// 导入所需的包
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_auth_ui/flutter_auth_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:page_transition/page_transition.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
import 'package:untitled2/screens/booking_screen.dart';
import 'package:untitled2/screens/done_services_screens.dart';
import 'package:untitled2/screens/home_screen.dart';
import 'package:untitled2/screens/staff_home_screen.dart';
import 'package:untitled2/screens/user_history_screen.dart';
import 'package:untitled2/state/state_management.dart';
import 'package:untitled2/utils/utils.dart';
// 导入 Firebase 配置文件
import 'firebase_options.dart';
// 主函数
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Barber Booking App',
onGenerateRoute: (settings) {
switch (settings.name) {
case '/staffHome':
return PageTransition(
settings: settings,
child: StaffHome(),
type: PageTransitionType.fade);
break;
case '/doneService':
return PageTransition(
settings: settings,
child: DoneService(),
type: PageTransitionType.fade);
break;
case '/home':
return PageTransition(
settings: settings,
child: HomePage(),
type: PageTransitionType.fade);
break;
case '/history':
return PageTransition(
settings: settings,
child: UserHistory(),
type: PageTransitionType.fade);
break;
case '/booking':
return PageTransition(
settings: settings,
child: BookingScreen(),
type: PageTransitionType.fade);
break;
default:
return null;
}
},
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends ConsumerWidget {
GlobalKey<ScaffoldState> scaffoldState = new GlobalKey();
// 处理登录
processLogin(BuildContext context) {
var user = FirebaseAuth.instance.currentUser;
if (user == null) {
FlutterAuthUi.startUi(
items: [AuthUiProvider.phone],
tosAndPrivacyPolicy: TosAndPrivacyPolicy(
tosUrl: 'https://google.com',
privacyPolicyUrl: 'https://google.com'),
androidOption: AndroidOption(
enableSmartLock: false, showLogo: true, overrideTheme: true))
.then((value) async {
// 刷新状态
context.read(userLogged).state = FirebaseAuth.instance.currentUser;
// 启动新的屏幕
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => HomePage()),
(Route<dynamic> route) => false,
);
}).catchError((e) {
ScaffoldMessenger.of(scaffoldState.currentContext!)
.showSnackBar(SnackBar(content: Text('${e.toString()}')));
});
} else {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => HomePage()),
(Route<dynamic> route) => false,
);
}
}
@override
Widget build(BuildContext context, watch) {
return SafeArea(
child: Scaffold(
key: scaffoldState,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/my_bg.png'),
fit: BoxFit.cover)),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
padding: const EdgeInsets.all(16),
width: MediaQuery.of(context).size.width,
child: FutureBuilder(
future: checkLoginState(context, false, scaffoldState),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(
child: CircularProgressIndicator(),
);
else {
var userState = snapshot.data as LOGIN_STATE;
print(userState);
if (userState == LOGIN_STATE.LOGGED) {
return Container();
} else {
return ElevatedButton.icon(
onPressed: () => processLogin(context),
icon: Icon(
Icons.phone,
color: Colors.white,
),
label: Text(
'Регистрация по номеру телефона',
style: TextStyle(color: Colors.white),
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.black)),
);
}
}
},
),
)
],
),
)));
}
// 检查登录状态
Future<LOGIN_STATE> checkLoginState(BuildContext context, bool fromLogin,
GlobalKey<ScaffoldState> scaffoldState) async {
if (!context.read(forceReload).state) {
await Future.delayed(
Duration(seconds: fromLogin == true ? 0 : 3),
() async {
try {
var token = await FirebaseAuth.instance.currentUser!.getIdToken();
//print('$token');
context.read(userToken).state = token;
CollectionReference userRef =
FirebaseFirestore.instance.collection('User');
DocumentSnapshot snapshotUser = await userRef
.doc(FirebaseAuth.instance.currentUser!.phoneNumber)
.get();
// 强制重新加载状态
context.read(forceReload).state = true;
if (snapshotUser.exists) {
Navigator.pushNamedAndRemoveUntil(
context, '/home', (route) => false);
return LOGIN_STATE.LOGGED;
} else {
var nameController = TextEditingController();
var addressController = TextEditingController();
Alert(
context: context,
title: 'Обновить данные',
content: Column(
children: [
TextField(
decoration: InputDecoration(
icon: Icon(Icons.account_circle), labelText: 'Имя'),
controller: nameController,
),
TextField(
decoration: InputDecoration(
icon: Icon(Icons.home), labelText: 'Адрес'),
controller: addressController,
)
],
),
buttons: [
DialogButton(
child: Text('Отмена'),
onPressed: () => Navigator.pop(context),
),
DialogButton(
child: Text('Обновить'),
onPressed: () {
// 更新到服务器
userRef
.doc(FirebaseAuth.instance.currentUser!.phoneNumber)
.set({
'name': nameController.text,
'address': addressController.text
}).then((value) async {
Navigator.pop(context);
ScaffoldMessenger.of(scaffoldState.currentContext!)
.showSnackBar(SnackBar(
content: Text('Данные успешно обновлены!'),
));
await Future.delayed(Duration(seconds: 1), () {
Navigator.pushNamedAndRemoveUntil(
context, '/home', (route) => false);
<details>
<summary>英文:</summary>
I solved my own problem with this code:
Main code:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_auth_ui/flutter_auth_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:page_transition/page_transition.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
import 'package:untitled2/screens/booking_screen.dart';
import 'package:untitled2/screens/done_services_screens.dart';
import 'package:untitled2/screens/home_screen.dart';
import 'package:untitled2/screens/staff_home_screen.dart';
import 'package:untitled2/screens/user_history_screen.dart';
import 'package:untitled2/state/state_management.dart';
import 'package:untitled2/utils/utils.dart';
import 'firebase_options.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Barber Booking App',
onGenerateRoute: (settings) {
switch (settings.name) {
case '/staffHome':
return PageTransition(
settings: settings,
child: StaffHome(),
type: PageTransitionType.fade);
break;
case '/doneService':
return PageTransition(
settings: settings,
child: DoneService(),
type: PageTransitionType.fade);
break;
case '/home':
return PageTransition(
settings: settings,
child: HomePage(),
type: PageTransitionType.fade);
break;
case '/history':
return PageTransition(
settings: settings,
child: UserHistory(),
type: PageTransitionType.fade);
break;
case '/booking':
return PageTransition(
settings: settings,
child: BookingScreen(),
type: PageTransitionType.fade);
break;
default:
return null;
}
},
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends ConsumerWidget {
GlobalKey<ScaffoldState> scaffoldState = new GlobalKey();
processLogin(BuildContext context) {
var user = FirebaseAuth.instance.currentUser;
if (user == null) {
FlutterAuthUi.startUi(
items: [AuthUiProvider.phone],
tosAndPrivacyPolicy: TosAndPrivacyPolicy(
tosUrl: 'https://google.com',
privacyPolicyUrl: 'https://google.com'),
androidOption: AndroidOption(
enableSmartLock: false, showLogo: true, overrideTheme: true))
.then((value) async {
//refresh state
context.read(userLogged).state = FirebaseAuth.instance.currentUser;
//start new screen
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => HomePage()),
(Route<dynamic> route) => false,
);
}).catchError((e) {
ScaffoldMessenger.of(scaffoldState.currentContext!)
.showSnackBar(SnackBar(content: Text('${e.toString()}')));
});
} else {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => HomePage()),
(Route<dynamic> route) => false,
);
}
}
@override
Widget build(BuildContext context, watch) {
return SafeArea(
child: Scaffold(
key: scaffoldState,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/my_bg.png'),
fit: BoxFit.cover)),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
padding: const EdgeInsets.all(16),
width: MediaQuery.of(context).size.width,
child: FutureBuilder(
future: checkLoginState(context, false, scaffoldState),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(
child: CircularProgressIndicator(),
);
else {
var userState = snapshot.data as LOGIN_STATE;
print(userState);
if (userState == LOGIN_STATE.LOGGED) {
return Container();
} else {
return ElevatedButton.icon(
onPressed: () => processLogin(context),
icon: Icon(
Icons.phone,
color: Colors.white,
),
label: Text(
'Регистрация по номеру телефона',
style: TextStyle(color: Colors.white),
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.black)),
);
}
}
},
),
)
],
),
)));
}
Future<LOGIN_STATE> checkLoginState(BuildContext context, bool fromLogin,
GlobalKey<ScaffoldState> scaffoldState) async {
if (!context.read(forceReload).state) {
await Future.delayed(
Duration(seconds: fromLogin == true ? 0 : 3),
() async {
try {
var token = await FirebaseAuth.instance.currentUser!.getIdToken();
//print('$token');
context.read(userToken).state = token;
CollectionReference userRef =
FirebaseFirestore.instance.collection('User');
DocumentSnapshot snapshotUser = await userRef
.doc(FirebaseAuth.instance.currentUser!.phoneNumber)
.get();
//Force reload state
context.read(forceReload).state = true;
if (snapshotUser.exists) {
Navigator.pushNamedAndRemoveUntil(
context, '/home', (route) => false);
return LOGIN_STATE.LOGGED;
} else {
var nameController = TextEditingController();
var addressController = TextEditingController();
Alert(
context: context,
title: 'Обновить данные',
content: Column(
children: [
TextField(
decoration: InputDecoration(
icon: Icon(Icons.account_circle), labelText: 'Имя'),
controller: nameController,
),
TextField(
decoration: InputDecoration(
icon: Icon(Icons.home), labelText: 'Адрес'),
controller: addressController,
)
],
),
buttons: [
DialogButton(
child: Text('Отмена'),
onPressed: () => Navigator.pop(context),
),
DialogButton(
child: Text('Обновить'),
onPressed: () {
//update to server
userRef
.doc(FirebaseAuth.instance.currentUser!.phoneNumber)
.set({
'name': nameController.text,
'address': addressController.text
}).then((value) async {
Navigator.pop(context);
ScaffoldMessenger.of(scaffoldState.currentContext!)
.showSnackBar(SnackBar(
content: Text('Данные успешно обновлены!'),
));
await Future.delayed(Duration(seconds: 1), () {
Navigator.pushNamedAndRemoveUntil(
context, '/home', (route) => false);
});
}).catchError((e) {
Navigator.pop(context);
ScaffoldMessenger.of(scaffoldState.currentContext!)
.showSnackBar(SnackBar(content: Text('$e')));
});
},
),
],
).show();
}
} catch (e) {
print(e);
return LOGIN_STATE.NOT_LOGIN;
}
},
);
}
return FirebaseAuth.instance.currentUser != null
? LOGIN_STATE.LOGGED
: LOGIN_STATE.NOT_LOGIN;
}
}
Home screen code:
import 'package:carousel_slider/carousel_slider.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:untitled2/model/image_model.dart';
import 'package:untitled2/state/state_management.dart';
import '../cloud_firestore/banner_ref.dart';
import '../cloud_firestore/lookbook_ref.dart';
import '../cloud_firestore/user_ref.dart';
import '../main.dart';
import '../model/user_model.dart';
import '../utils/utils.dart';
class HomePage extends ConsumerWidget {
@override
Widget build(BuildContext context, watch) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: Color(0xFFDFDFDF),
body: SingleChildScrollView(
child: Column(children: [
//user profile
FutureBuilder(
future: getUserProfiles(context,
FirebaseAuth.instance.currentUser!.phoneNumber!),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(
child: CircularProgressIndicator(),
);
else {
var userModel = snapshot.data as UserModel;
return Container(
decoration: BoxDecoration(color: Color(0xFF383838)),
padding: const EdgeInsets.all(16),
child: Row(
children: [
CircleAvatar(
child: Icon(
Icons.person,
color: Colors.white,
size: 30,
),
maxRadius: 30,
backgroundColor: Colors.black,
),
SizedBox(
width: 30,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${userModel.name}',
style: GoogleFonts.robotoMono(
fontSize: 22,
color: Colors.white,
fontWeight: FontWeight.bold),
),
Text(
'${userModel.address}',
overflow: TextOverflow.ellipsis,
style: GoogleFonts.robotoMono(
fontSize: 18,
color: Colors.white,
),
)
],
),
),
IconButton(icon: Icon(Icons.logout,
color: Colors.white,),
onPressed: () =>
signOut(context),),
context.read(userInformation).state.isStaff ?
IconButton(icon: Icon(Icons.admin_panel_settings,
color: Colors.white,),
onPressed: () =>
Navigator.of(context).pushNamed(
'/staffHome'),) : Container()
],
),
);
}
}),
//Menu
Padding(
padding: const EdgeInsets.all(4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: GestureDetector(
onTap: () => Navigator.pushNamed(context, '/booking'),
child: Container(
child: Card(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.book_online,
size: 50,
),
Text(
'Запись',
style: GoogleFonts.robotoMono(),
)
],
),
),
),
),
),
),
Expanded(
child: GestureDetector(onTap: () => Navigator.pushNamed(context, '/history'),
child: Container(
child: Card(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.history,
size: 50,
),
Text(
'История',
style: GoogleFonts.robotoMono(),
)
],
),
),
),
),),
)
],
),
),
//Banner
FutureBuilder(
future: getBanners(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(
child: CircularProgressIndicator(),
);
else {
var banners = snapshot.data as List<ImageModel>;
return CarouselSlider(
options: CarouselOptions(
enlargeCenterPage: true,
aspectRatio: 3.0,
autoPlay: true,
autoPlayInterval: Duration(seconds: 3)),
items: banners
.map((e) => Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(e.image),
),
))
.toList());
}
}),
//Lookbook
Padding(
padding: const EdgeInsets.all(8),
child: Row(
children: [
Text(
'Примеры наших работ',
style: GoogleFonts.robotoMono(fontSize: 24),
)
],
),
),
FutureBuilder(
future: getLookbook(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(
child: CircularProgressIndicator(),
);
else if (!snapshot.hasData || snapshot.data == null)
return SizedBox.shrink();
else {
var lookbook = snapshot.data as List<ImageModel>;
return Column(
children: lookbook
.map((e) => Container(
padding: const EdgeInsets.all(8),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(e.image),
),
))
.toList(),
);
}
}),
]),
),
));
}
Future<void> signOut(BuildContext context) async {
await FirebaseAuth.instance.signOut().then((value) => Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => MyHomePage())));
}
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论