24

I'm trying to detect that user is no longer authenticated and redirect user to login. This is how I'm doing it

  Widget build(BuildContext context) {
    return FutureBuilder(
        future: _getData(context),
        builder: (context, snapshot) {
          try {
            if (snapshot.hasError && _isAuthenticationError(snapshot.error)) {
                Navigator.push(context, MaterialPageRoute(builder: (context) => LoginView()));
            }

Unfortunately doing navigation on build is not working. It throws this error

flutter: setState() or markNeedsBuild() called during build.
flutter: This Overlay widget cannot be marked as needing to build because the framework is already in the
flutter: process of building widgets.  A widget can be marked as needing to be built during the build 

I cannot just return LoginView widget since parent widget containts app bar and floating button and login view needs to be displayed without these controlls.. I need to navigate.

Is it possible to do it?

1
  • How do users log in? Is it by firebase?
    – DomingoMG
    Commented Jan 18, 2020 at 19:35

3 Answers 3

57

Wrap it in Future.microtask. This will schedule it to happen on the next async task cycle (i.e. after build is complete).

Future.microtask(() => Navigator.push(
  context, 
  MaterialPageRoute(builder: (context) => LoginView())
));
7
  • But in this case, I am having an endless loop. Are there any other ways you can do that?
    – Valary o
    Commented May 7, 2020 at 19:28
  • 1
    @Valaryo Future.microtask only fires once, so a loop is impossible if you are doing it right. The only way I can imagine this causing an endless loop is if you are using it to navigate to the page that you are already on and loading the page is what triggers the navigation. There could also be an issue where if you are trying to navigate during the build method and the widget is rebuilding many times, you will continue to queue up navigations after the first one already triggered. (This is why doing non-UI stuff in the build method is generally a bad idea.)
    – Abion47
    Commented May 7, 2020 at 19:39
  • yeah, apparently I am indeed doing that wrong. I am more than sure about that at the moment. I am just getting into the way of things with Flutter. I've tried all possible ways to accomplish that but I either have an error related to SetState or something with that or something with MediaQuery. In short, I've got a wrapper which holds three components: header, footer and a viewWrapper (with a page view). And here you are right. I am scrolling through the pages and my last page is a Login Widget, but having reached it I want to get out of the pageView mode (where I have footer and header)
    – Valary o
    Commented May 7, 2020 at 19:46
  • so I then try to redirect to a Login page to have it fullscreen and kinda static. But my login is not on Login page but I already tried to put in inside footer and the top-level wrapper.
    – Valary o
    Commented May 7, 2020 at 19:48
  • I use Provider to watch the state. Do you have any ideas on how I can solve it?
    – Valary o
    Commented May 7, 2020 at 19:50
0

Streams in flutter

The usual thing is to use a flow where user changes occur. When the user logs off, he detects that change and can direct it to another window.

-3

problem here :

snapshot.hasError && _isAuthenticationError(snapshot.error)

Instead of this use OR

snapshot.hasError || _isAuthenticationError(snapshot.error)

Not the answer you're looking for? Browse other questions tagged or ask your own question.