Flutter: Multi provider with consumer not rebuilding widget

Viewed 502

I'm using multi provider with consumer to route my app based on the authentication status. The app routes redirects correctly during the first render but when the authentication status change after the the first render, it fails to reroute.

I have multiple providers but the rest works fine except the AuthProvider.

Future<void> main() async {
      runApp(
        MultiProvider(
          providers: [
            ChangeNotifierProvider(create: (_) => AuthProvider()),
            ...
          ],
          child: const App(),
        ),
      );
    }
    
    class App extends StatefulWidget {
      const App({Key? key, this.title}) : super(key: key);
    
      final String? title;
    
      @override
      State<App> createState() => _AppState();
    }
    
    class _AppState extends State<App> {
      @override
      void initState() {
        super.initState();
        ...
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          ...,
          routes: {
            '/': (context) => const Router(),
            '/login': (context) => const LoginScreen(),
            '/register': (context) => const RegisterScreen(),
            ...
          },
        );
      }
    }

When I inspect the authentication status in the switch statement below, the status is changing but the app doesn't reroute.

    class Router extends StatelessWidget {
      const Router({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Consumer<AuthProvider>(builder: (context, auth, child) {
          switch (auth.status) {
            case AuthStatus.uninitialized:
              return const LoadingScreen();
            case AuthStatus.authenticating:
              return const LoadingScreen();
            case AuthStatus.unauthenticated:
              return const IntroScreen();
            case AuthStatus.authenticated:
              return const MainScreen();
            default:
              return const IntroScreen();
          }
        });
      }
    }


class AuthProvider with ChangeNotifier, DiagnosticableTreeMixin {
  AuthStatus _status = AuthStatus.uninitialized;
  JwtToken? _jwtToken;

  AuthStatus get status => _status;

  JwtToken? get jwtToken => _jwtToken;

  AuthProvider() {
    init();
  }

  init() async {
    _jwtToken = await getJwtToken();

    if (_jwtToken != null) {
      if (!JwtDecoder.isExpired(_jwtToken!
              .accessToken)) {              
        _status = AuthStatus.authenticated;
        notifyListeners();
      } else {
        _refreshLogin();
      }
    } else {
      _status = AuthStatus.unauthenticated;
      notifyListeners();
    }
  }

  _refreshLogin() async {
    _status = AuthStatus.authenticating;
    notifyListeners();
     ...
      _status = AuthStatus.authenticated;    
      notifyListeners();
    }
  }

  login(String username, String password) async {
    _status = AuthStatus.authenticating;
    notifyListeners();    
    ...
      _status = AuthStatus.authenticated;    
      notifyListeners();
    }
  }
}
0 Answers
Related