无法在Flutter中使用提供程序来处理身份验证流程

时间:2020-07-16 07:22:32

标签: flutter flutter-provider state-management flutter-state

如果任何人都无法理解我的问题,请告知

我已经使用提供程序包来处理身份验证流程。 我正在做的是:Main.dart->身份处理程序小部件(其中包含用于检查onAuthChange的流生成器​​)->页面处理程序(如果用户是新用户,它将把用户带到入职屏幕,然后将其转移到登录名登录页面后,将检查用户是否存在数据->如果存在,则进入主屏幕->主屏幕包含3个标签。在主选项卡中有退出按钮,但是当我按时它不起作用。帮助我。

Main.dart

Provider<AuthBase>(
      create: (context)=>Auth(),
      child: MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Rapport',
          theme: ThemeData(
            primaryColor: Color(0xFFE3F2FD),
            visualDensity: VisualDensity.adaptivePlatformDensity,
            pageTransitionsTheme: PageTransitionsTheme(
              builders: {
                TargetPlatform.android: CustomPageTransitionsBuilder(),
                TargetPlatform.iOS: CustomPageTransitionsBuilder(),
              },
            ),
          ),

          /*This is the routes table. Add all the route names used inside the app here
        Add the route name where the route is made as static const String, so as to you don't need to remember anything.
         */
          routes: {
            //the route name / stands for home / first route in the app.
            '/': (ctx) {
              return SplashScreen.navigate(
                name: 'assets/splash.flr',
                next: (context) {
                  print(isLogin.toString());
                  return AuthWidgetBuilder(dataExists: myData.length==0,isLogin: isLogin,builder: (context, userSnapshot,isLogin,dataExist) {
                    return Scaffold(
                      body: AuthWidget(userSnapshot: userSnapshot,dataExists: myData.length==0,isLogin: isLogin,),
                    );
                  });
                },
                startAnimation: 'Untitled',
                until: () => Future.delayed(Duration(seconds: 4)),
                backgroundColor: Colors.white,
              );
            },
            LoginScreen.loginRoute: (ctx) => LoginScreen(),
            CheckUser.checkRoute: (ctx) => CheckUser(),
            OnboardingScreen.onBoardRoute: (ctx) => OnboardingScreen(),
            StudentInfo.studentRoute: (ctx) => StudentInfo(),
            PersonalDetails.routeName:(ctx) => PersonalDetails(),
            ProfessionalDetails.routeName:(ctx) => ProfessionalDetails(),
            AddressDetails.routeName: (ctx) => AddressDetails(),
            TeacherHomeScreen.routeName:(ctx)=>TeacherHomeScreen(),
            TeacherVerification.routeName:(ctx)=>TeacherVerification(),
            StudentHomeScreen.routeName : (ctx)=>StudentHomeScreen(),
          },
        ),
    );

Auth_Widget_Builder

class AuthWidgetBuilder extends StatelessWidget {
  const AuthWidgetBuilder({Key key, @required this.builder,@required this.isLogin,@required this.dataExists}) : super(key: key);
  final Widget Function(BuildContext, AsyncSnapshot<User>,String,bool) builder;
  final String isLogin;
  final bool dataExists;


  @override
  Widget build(BuildContext context) {
    print('AuthWidgetBuilder rebuild');
    print(dataExists);
    final authService =
    Provider.of<AuthBase>(context, listen: false);
    return StreamBuilder<User>(
      stream: authService.onAuthStateChanged,
      builder: (context, snapshot) {
        print('StreamBuilder: ${snapshot.connectionState}');
        final User user = snapshot.data;
        if (user != null) {
          SharedPrefFunction().saveLoginPreference();
          return MultiProvider(
            providers: [
              Provider<User>.value(value: user),
            ],
            child: builder(context, snapshot,'true',dataExists),
          );
        }
        return builder(context, snapshot,isLogin,dataExists);
      },
    );
  }
}

Auth.Widget

class AuthWidget extends StatelessWidget {
  const AuthWidget({Key key, @required this.userSnapshot,this.dataExists,this.isLogin}) : super(key: key);
  final AsyncSnapshot<User> userSnapshot;
  final String isLogin;
  final bool dataExists;

  @override
  Widget build(BuildContext context) {
    if (userSnapshot.connectionState == ConnectionState.active) {
      if(isLogin == null){
        return OnboardingScreen();
      }
      else{
        return userSnapshot.hasData ? CheckUser(dataExist: dataExists,) : LoginScreen();
      }
    }
    return Scaffold(
      body: Center(
        child: CircularProgressIndicator(),
      ),
    );
  }
}

在checkUser.dart中是否存在数据

homePage(BuildContext context) {
    print('checkUser');
    if (dataExists) {
      return Scaffold(
        body: SafeArea(
          child: Container(
            child: Column(
              children: <Widget>[
                Text(
                  'Welcome',
                  style: kTextStyle,
                ),
                FlatButton.icon(
                  onPressed: () {
                    setState(() {
                      Navigator.of(context).pushReplacementNamed(
                        StudentHomeScreen.routeName,   //This line is changed by me. This code is not correct and needs to be changed.
                      );
                    });
                  },
                  icon: Icon(Icons.home),
                  label: Text('Home'),
                ),
              ],
            ),
          ),
        ),
      );
    } else {
      return getInfoPage();
    }
  }

Student_Home_Screen.dart

class _StudentHomeState extends State<StudentHomeScreen> {
  bool _isProfilePicSet = false;
  int _currentTabIndex = 1;
  var _tabs = [
    Center(
      child: Text('Search Tab'),
    ),
    HomeTab(),
    Center(
      child: Text('Profile Tab'),
    ),
  ];

  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;
    return Scaffold(
      backgroundColor: Colors.white,
      body: _tabs[_currentTabIndex],
      bottomNavigationBar: BottomNavigationBar(
//        type: BottomNavigationBarType.shifting,
        backgroundColor: Colors.white,
//        fixedColor: Colors.black,
        iconSize: 24,
        selectedIconTheme: IconThemeData(
          color: themeColor,
          opacity: 1,
        ),
        unselectedIconTheme: IconThemeData(
          color: themeColor,
          opacity: 0.6,
        ),
        showUnselectedLabels: false,
        showSelectedLabels: true,
        elevation: 10,
        currentIndex: _currentTabIndex,
        onTap: (index) {
          setState(() {
            _currentTabIndex = index;
          });
        },
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            title: Text(
              'Search',
              style: subhead2.copyWith(color: themeColor),
            ),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text(
              'Home',
              style: subhead2.copyWith(color: themeColor),
            ),
          ),
          BottomNavigationBarItem(
            icon: CircleAvatar(
              backgroundImage: _isProfilePicSet
                  ? NetworkImage('set link here')
                  : AssetImage('assets/images/default.png'),
              maxRadius: 12,
            ),
            title: Text(
              'Profile',
              style: subhead2.copyWith(color: themeColor),
            ),
          ),
        ],
      ),
    );
  }
}

在“首页”标签中,退出按钮功能

  Future<void> _signOut(BuildContext context) async {
    try {
      final auth = Provider.of<AuthBase>(context, listen: false);
      await auth.signOut();
    } catch (e) {
      print(e);
    }
  }

2 个答案:

答案 0 :(得分:1)

这可能会对您有所帮助。我不确定,但这对我有用

退出功能

Future _signOut() async {
    try {
      return await auth.signOut();
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

功能用法

IconButton(
  onPressed: () async {
    await _auth.signOut();
    MaterialPageRoute(
      builder: (context) => Login(),
    );
  },
  icon: Icon(Icons.exit_to_app),
),

答案 1 :(得分:0)

您需要将AuthWidgetBuilder作为顶级窗口小部件(最好在MaterialApp之上),以便在登录/注销事件时重建整个窗口小部件树。

您可以使SplashScreen成为孩子,并具有一些条件逻辑来决定是否应该显示它。

顺便说一句,如果您的启动屏幕根本不包含任何动画,那么您根本不需要小部件,并且您可以在iOS上使用启动屏幕,或者在Android上使用等效屏幕(有关此在线课程的教程)。 通过@ bizz84