提供商登录注销异常

问题描述

我正在尝试使用提供者创建一个简单的身份验证流程。我有三页:

  1. LoginPage
  2. OnboardingPage
  3. 主页

此应用的流程为:

  1. 如果用户是第一次打开该应用程序,则他/她将被重定向到入门菜单,然后登录到首页。
  2. 对于第二次用户,该应用程序首先检查登录状态,并重定向到->主页或直接转到主页。

这是我在代码中的设置:

main.dart

void main() {
  runApp(MultiProvider(providers: [
    ChangeNotifierProvider<StorageHelper>(create: (_) => StorageHelper()),ChangeNotifierProvider<AuthProvider>(create: (_) => AuthProvider()),],child: MyApp()));
}

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return Consumer<AuthProvider>(builder: (final BuildContext context,final AuthProvider authProvider,final Widget child) {
        print(authProvider.isAuthenticated); // this is false whenever I //click the logout from category(or other pushed pages) but the below ternary //operation is not executing
      return MaterialApp(
          title: 'My Poor App',debugShowCheckedModeBanner: false,theme: ThemeData(
            primaryColor: Color(0xff29c17e),visualDensity: VisualDensity.adaptivePlatformDensity,),home: authProvider.isAuthenticated ? HomeScreen() : LoginScreen(),onGenerateRoute: Router.onGenerateRoute,);
    });
  }
}

LoginScreen.dart

class LoginScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final authProvider = Provider.of<AuthProvider>(context,listen: false);
    return Scaffold(
      body: Center(
          child: MaterialButton(
              onPressed: () async {
                await authProvider.emailLogin('user@email.com','pass');
              },child: Text('Login'))),);
  }
}

HomeScreen.dart

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final auth = Provider.of<AuthProvider>(context,listen: false);
    return Scaffold(
      body: Center(
        child: MaterialButton(
                elevation: 2,onPressed: () {
                  Navigator.push(
                      context,MaterialPageRoute(
                          builder: (context) => CategoryScreen()));
                },child: Text('Reset')),);
  }
}

AuthProvider.dart

class AuthProvider extends ChangeNotifier {
  bool _isAuthenticated = false;

  bool get isAuthenticated => _isAuthenticated;

  set isAuthenticated(bool isAuth) {
    _isAuthenticated = isAuth;
    notifyListeners();
  }

  Future emailLogin(String email,String password) async {
    isAuthenticated = true;
  }

  Future logout() async {
    isAuthenticated = false;
  }
}

如果我使用Provider.of<AuthProvider>(context).logout()从主页注销,则工作正常。但是,如果我pushpushReplacement一条新路由并尝试从新路由注销(只是说我从首页导航到类别页面并尝试从那里注销),则不会重定向到LoginPage。如果我打印isAuthenticated的值,它将打印false,但是使用者没有监听或至少没有对变量更改做出反应。

请不要将此问题标记为重复,我搜索了许多其他类似的问题,但没有一个适合我的情况。

编辑: CategoryScreen.dart

class CategoryScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(
          onPressed: () {
            final auth = Provider.of<AuthProvider>(context,listen: false);
            auth.logout();
            // print(auth.isAuthenticated);
          },child: Text('Category Logout'),);
  }
}

The widget tree of first time login page

The widget tree of home page

The widget tree after the navigator.pushAndRemoveUntil(CategoryScreen)

解决方法

我想您的问题是您没有在Consumer的{​​{1}}中将logout用作home。看看,如果它对您有用

main.dart

MaterialApp

由于// needs to listen to the changes,to make changes home: Consumer<AuthProvider>( builder: (context,authProvider,child){ return authProvider.isAuthenticated ? HomeScreen() : LoginScreen(); } ) 不在您的Consumer中,即使更改了值,它也无法按照提供程序为您更新视图。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...