skip to Main Content

I have worked with Flutter now and I know the cycles of the widgets quite well. I have a Login-Logic inside my code:

class Login extends StatefulWidget {
  const Login({super.key});

  @override
  State<Login> createState() => _LoginWidgetState();
}

class _LoginWidgetState extends State<Login> with WidgetsBindingObserver {

  @override
  void initState() {
    super.initState();
    Connectivity().checkConnectivity().then((connectivityResult) {
      setState(() {
        isConnected = connectivityResult != ConnectivityResult.none;
      });
    });

    _connectivitySubscription = Connectivity()
        .onConnectivityChanged
        .listen((ConnectivityResult result) {
      if (result == ConnectivityResult.none) {
        setState(() {
          isConnected = false;
        });
      } else {
        setState(() {
          isConnected = true;
        });
      }
    });
    print("init");
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    print("dispose-login");
    _connectivitySubscription.cancel();
    WidgetsBinding.instance?.removeObserver(this);
    super.dispose();
  }

... more code
}

In this view, the form and validation happens. As soon as everything fine, I call this function:

login(String email, String password) async {
ApiService apiService = ApiService(this);

final response = await apiService.postUnauthenticated(
    "", {"email": email, "password": password});

if (response.statusCode == 200) {
  final jsonResponse = jsonDecode(response.body);
  final token = jsonResponse['token'] as String;
  apiService.setAuthToken(token);
  saveAuthorizationToken(token);
  _token = token;
  _status = Status.authenticated;
  print("Status: Authenticated");
  notifyListeners();
} else {
  apiService.removeAuthToken();
  removeAuthorizationToken();
  _status = Status.unauthenticated;
  notifyListeners();
}

notifyListeners();
getAccessToken();
return response.statusCode;

}

In which I call the Api and set a status based on the output. With this status, I check which view to show in app.dart:

  @override
  Widget build(BuildContext context) {
    final authProvider = Provider.of<AuthProvider>(context, listen: false);
    return Consumer<AuthProvider>(
      builder: (context, user, child) {
        switch (user.status) {
          case Status.hasBikes:
            print("hasBike");
            return const HomePage();
          case Status.uninitialized:
            print("uninitialized");
            return const InitView();
          case Status.unauthenticated:
            print("unauth");
            return const Login();
          case Status.authenticated:
            print("auth");
            return const LoadView();
          case Status.unpaired:
            print("unpair");
            return const PairingHome(hasError: false);
          case Status.error:
            print("error");
            return const ServerError();
          default:
            return const InitView();
        }
      },
    );
  }

In another StatefulWidget the user can logout and gets redirected to the login page. This looks like this:

onTap: () async {
              Provider.of<AuthProvider>(context, listen: false).logout();
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => const Login()),
              );
            }

So the problem is following. After the download, the user is on the login page. The login works flawless, including the redirect. But when the user logs out and tries to login again, the user gets logged in but not redirected. He has to reopen the app before he is logged in. And the weirdest part is that after login, the dispose-function of the Login-Page is called (i checked with a print), but the page is still displayed.

Do you have any idea about what could be the problem?

2

Answers


  1. I think you can try by removing listen : false in provider when you calling in widget

    Login or Signup to reply.
  2. You are pushing to another, a second, Login screen. I believe you shouldn’t be pushing anything. It will already be handled automatically by the

    switch (user.status) {
    

    you have.
    So try to change

        onTap: () async {
                  Provider.of<AuthProvider>(context, listen: false).logout();
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => const Login()),
                  );
                }
    

    to

        onTap: () async {
                  Provider.of<AuthProvider>(context, listen: false).logout();
                }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search