如何在Flutter中使用Firebase身份验证创建一个登出按钮?

huangapple go评论56阅读模式
英文:

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:

  1. 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 calling await 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.

  2. Check User Authentication State: In your MyHomePage widget, you can check the user's authentication state in the build method to determine whether to show the login button or proceed to the home page. Instead of using a cached value, you can use FirebaseAuth.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 &#39;package:cloud_firestore/cloud_firestore.dart&#39;;
    import &#39;package:firebase_auth/firebase_auth.dart&#39;;
    import &#39;package:firebase_core/firebase_core.dart&#39;;
    import &#39;package:flutter/material.dart&#39;;
    import &#39;package:flutter_auth_ui/flutter_auth_ui.dart&#39;;
    import &#39;package:flutter_riverpod/flutter_riverpod.dart&#39;;
    import &#39;package:page_transition/page_transition.dart&#39;;
    import &#39;package:rflutter_alert/rflutter_alert.dart&#39;;
    import &#39;package:untitled2/screens/booking_screen.dart&#39;;
    import &#39;package:untitled2/screens/done_services_screens.dart&#39;;
    import &#39;package:untitled2/screens/home_screen.dart&#39;;
    import &#39;package:untitled2/screens/staff_home_screen.dart&#39;;
    import &#39;package:untitled2/screens/user_history_screen.dart&#39;;
    import &#39;package:untitled2/state/state_management.dart&#39;;
    import &#39;package:untitled2/utils/utils.dart&#39;;
    
    import &#39;firebase_options.dart&#39;;
    
    Future&lt;void&gt; 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: &#39;Barber Booking App&#39;,
          onGenerateRoute: (settings) {
            switch (settings.name) {
              case &#39;/staffHome&#39;:
                return PageTransition(
                    settings: settings,
                    child: StaffHome(),
                    type: PageTransitionType.fade);
                break;
              case &#39;/doneService&#39;:
                return PageTransition(
                    settings: settings,
                    child: DoneService(),
                    type: PageTransitionType.fade);
                break;
              case &#39;/home&#39;:
                return PageTransition(
                    settings: settings,
                    child: HomePage(),
                    type: PageTransitionType.fade);
                break;
              case &#39;/history&#39;:
                return PageTransition(
                    settings: settings,
                    child: UserHistory(),
                    type: PageTransitionType.fade);
                break;
              case &#39;/booking&#39;:
                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&lt;ScaffoldState&gt; scaffoldState = new GlobalKey();
    
      processLogin(BuildContext context) {
        var user = FirebaseAuth.instance.currentUser;
        if (user == null) {
          FlutterAuthUi.startUi(
              items: [AuthUiProvider.phone],
              tosAndPrivacyPolicy: TosAndPrivacyPolicy(
                  tosUrl: &#39;https://google.com&#39;,
                  privacyPolicyUrl: &#39;https://google.com&#39;),
              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) =&gt; HomePage()),
                  (Route&lt;dynamic&gt; route) =&gt; false,
            );
          }).catchError((e) {
            ScaffoldMessenger.of(scaffoldState.currentContext!)
                .showSnackBar(SnackBar(content: Text(&#39;${e.toString()}&#39;)));
          });
        } else {
          Navigator.of(context).pushAndRemoveUntil(
            MaterialPageRoute(builder: (context) =&gt; HomePage()),
                (Route&lt;dynamic&gt; route) =&gt; false,
          );
        }
      }
    
      @override
      Widget build(BuildContext context, watch) {
        return SafeArea(
            child: Scaffold(
                key: scaffoldState,
                body: Container(
                  decoration: BoxDecoration(
                      image: DecorationImage(
                          image: AssetImage(&#39;assets/images/my_bg.png&#39;),
                          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: () =&gt; processLogin(context),
                                  icon: Icon(
                                    Icons.phone,
                                    color: Colors.white,
                                  ),
                                  label: Text(
                                    &#39;Регистрация по номеру телефона&#39;,
                                    style: TextStyle(color: Colors.white),
                                  ),
                                  style: ButtonStyle(
                                      backgroundColor:
                                      MaterialStateProperty.all(Colors.black)),
                                );
                              }
                            }
                          },
                        ),
                      )
                    ],
                  ),
                )));
      }
      Future&lt;LOGIN_STATE&gt; checkLoginState(BuildContext context, bool fromLogin,
          GlobalKey&lt;ScaffoldState&gt; 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(&#39;$token&#39;);
                context.read(userToken).state = token;
                CollectionReference userRef =
                    FirebaseFirestore.instance.collection(&#39;User&#39;);
                DocumentSnapshot snapshotUser = await userRef
                    .doc(FirebaseAuth.instance.currentUser!.phoneNumber)
                    .get();
                //Force reload state
                context.read(forceReload).state = true;
                if (snapshotUser.exists) {
                  Navigator.pushNamedAndRemoveUntil(
                      context, &#39;/home&#39;, (route) =&gt; false);
                  return LOGIN_STATE.LOGGED;
                } else {
                  var nameController = TextEditingController();
                  var addressController = TextEditingController();
                  Alert(
                    context: context,
                    title: &#39;Обновить данные&#39;,
                    content: Column(
                      children: [
                        TextField(
                          decoration: InputDecoration(
                              icon: Icon(Icons.account_circle), labelText: &#39;Имя&#39;),
                          controller: nameController,
                        ),
                        TextField(
                          decoration: InputDecoration(
                              icon: Icon(Icons.home), labelText: &#39;Адрес&#39;),
                          controller: addressController,
                        )
                      ],
                    ),
                    buttons: [
                      DialogButton(
                        child: Text(&#39;Отмена&#39;),
                        onPressed: () =&gt; Navigator.pop(context),
                      ),
                      DialogButton(
                        child: Text(&#39;Обновить&#39;),
                        onPressed: () {
                          //update to server
                          userRef
                              .doc(FirebaseAuth.instance.currentUser!.phoneNumber)
                              .set({
                            &#39;name&#39;: nameController.text,
                            &#39;address&#39;: addressController.text
                          }).then((value) async {
                            Navigator.pop(context);
                            ScaffoldMessenger.of(scaffoldState.currentContext!)
                                .showSnackBar(SnackBar(
                              content: Text(&#39;Данные успешно обновлены!&#39;),
                            ));
                            await Future.delayed(Duration(seconds: 1), () {
                              Navigator.pushNamedAndRemoveUntil(
                                  context, &#39;/home&#39;, (route) =&gt; false);
                            });
                          }).catchError((e) {
                            Navigator.pop(context);
                            ScaffoldMessenger.of(scaffoldState.currentContext!)
                                .showSnackBar(SnackBar(content: Text(&#39;$e&#39;)));
                          });
                        },
                      ),
                    ],
                  ).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 &#39;package:carousel_slider/carousel_slider.dart&#39;;
    import &#39;package:firebase_auth/firebase_auth.dart&#39;;
    import &#39;package:flutter/material.dart&#39;;
    import &#39;package:flutter/src/widgets/framework.dart&#39;;
    import &#39;package:flutter_riverpod/flutter_riverpod.dart&#39;;
    import &#39;package:google_fonts/google_fonts.dart&#39;;
    import &#39;package:untitled2/model/image_model.dart&#39;;
    import &#39;package:untitled2/state/state_management.dart&#39;;
    import &#39;../cloud_firestore/banner_ref.dart&#39;;
    import &#39;../cloud_firestore/lookbook_ref.dart&#39;;
    import &#39;../cloud_firestore/user_ref.dart&#39;;
    import &#39;../main.dart&#39;;
    import &#39;../model/user_model.dart&#39;;
    import &#39;../utils/utils.dart&#39;;
    
    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(
                                        &#39;${userModel.name}&#39;,
                                        style: GoogleFonts.robotoMono(
                                            fontSize: 22,
                                            color: Colors.white,
                                            fontWeight: FontWeight.bold),
                                      ),
                                      Text(
                                        &#39;${userModel.address}&#39;,
                                        overflow: TextOverflow.ellipsis,
                                        style: GoogleFonts.robotoMono(
                                          fontSize: 18,
                                          color: Colors.white,
                                        ),
                                      )
                                    ],
                                  ),
                                ),
                                IconButton(icon: Icon(Icons.logout,
                                  color: Colors.white,),
                                  onPressed: () =&gt;
                                  signOut(context),),
                                context.read(userInformation).state.isStaff ?
                                IconButton(icon: Icon(Icons.admin_panel_settings,
                                  color: Colors.white,),
                                  onPressed: () =&gt;
                                      Navigator.of(context).pushNamed(
                                          &#39;/staffHome&#39;),) : Container()
                              ],
                            ),
                          );
                        }
                      }),
              //Menu
              Padding(
                padding: const EdgeInsets.all(4),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Expanded(
                      child: GestureDetector(
                        onTap: () =&gt; Navigator.pushNamed(context, &#39;/booking&#39;),
                        child: Container(
                          child: Card(
                            child: Padding(
                              padding: const EdgeInsets.all(8),
                              child: Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: [
                                  Icon(
                                    Icons.book_online,
                                    size: 50,
                                  ),
                                  Text(
                                    &#39;Запись&#39;,
                                    style: GoogleFonts.robotoMono(),
                                  )
                                ],
                              ),
                            ),
                          ),
                        ),
                      ),
                    ),
                    Expanded(
                      child: GestureDetector(onTap: () =&gt; Navigator.pushNamed(context, &#39;/history&#39;),
                      child: Container(
                        child: Card(
                          child: Padding(
                            padding: const EdgeInsets.all(8),
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                Icon(
                                  Icons.history,
                                  size: 50,
                                ),
                                Text(
                                  &#39;История&#39;,
                                  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&lt;ImageModel&gt;;
                      return CarouselSlider(
                          options: CarouselOptions(
                              enlargeCenterPage: true,
                              aspectRatio: 3.0,
                              autoPlay: true,
                              autoPlayInterval: Duration(seconds: 3)),
                          items: banners
                              .map((e) =&gt; Container(
                                    child: ClipRRect(
                                      borderRadius: BorderRadius.circular(8),
                                      child: Image.network(e.image),
                                    ),
                                  ))
                              .toList());
                    }
                  }),
              //Lookbook
              Padding(
                padding: const EdgeInsets.all(8),
                child: Row(
                  children: [
                    Text(
                      &#39;Примеры наших работ&#39;,
                      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&lt;ImageModel&gt;;
                      return Column(
                        children: lookbook
                            .map((e) =&gt; Container(
                                  padding: const EdgeInsets.all(8),
                                  child: ClipRRect(
                                    borderRadius: BorderRadius.circular(8),
                                    child: Image.network(e.image),
                                  ),
                                ))
                            .toList(),
                      );
                    }
                  }),
            ]),
          ),
        ));
      }
    
      Future&lt;void&gt; signOut(BuildContext context) async {
        await FirebaseAuth.instance.signOut().then((value) =&gt; Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) =&gt; MyHomePage())));
      }
    }

</details>



huangapple
  • 本文由 发表于 2023年5月13日 14:35:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76241402.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定