I have the following main():

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  final authBloc = AuthBloc();
  final otroUsuarioBloc = OtroUsuarioBloc();
  final firestoreService = FirestoreService();

  FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;

  runApp(
    EasyLocalization(
        supportedLocales: [
          Locale('en', 'US'),
          Locale('es', 'ES'),
          Locale('de', 'DE'),
          Locale('fr', 'FR')
        ],
        path: 'assets/lang', // <-- change patch to your
        fallbackLocale: Locale('es', 'ES'),
        child: MultiProvider(
            providers: [
              ChangeNotifierProvider(create: (_) => PostsProvider()),
              ChangeNotifierProvider(create: (_) => FuegosPostsProvider()),
              ChangeNotifierProvider(create: (_) => ComentariosPostsProvider()),
              ChangeNotifierProvider(create: (_) => UsuarioProvider()),
              ChangeNotifierProvider(create: (_) => VisitasSpotProvider()),
              ChangeNotifierProvider(create: (_) => CheckInSpotProvider()),
              ChangeNotifierProvider(create: (_) => UserSportsProvider()),
              ChangeNotifierProvider(create: (_) => SeguidoresProvider()),
              ChangeNotifierProvider(create: (_) => UsuarioActualProvider()),
              ChangeNotifierProvider(create: (_) => AmigosProvider()),
              ChangeNotifierProvider(create: (_) => MensajesChatProvider()),
              ChangeNotifierProvider(create: (_) => SpotsProvider()),
              ChangeNotifierProvider(
                  create: (_) => EntradasSalidasSpotProvider()),
              ChangeNotifierProvider(create: (_) => UsuarioSharedProvider()),
              ChangeNotifierProvider(create: (_) => DatosUsuarioProvider()),
              ChangeNotifierProvider(create: (_) => LogeadoProvider()),
              Provider(create: (context) => authBloc),
              Provider(create: (context) => otroUsuarioBloc),
            ],
            child: MaterialApp(
                title: "Mov-Map",
                home: MyApp(),
                onGenerateRoute: Routes.materialRoutes,
                theme: ThemeData(scaffoldBackgroundColor: Colors.white)))),
  );
}

And also the following MyApp():

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        localizationsDelegates: context.localizationDelegates,
        supportedLocales: context.supportedLocales,
        locale: context.locale,
        home: SplashScreen()); // define it once at root level.
  }
}

class SplashScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return SplashScreenState();
  }
}

class SplashScreenState extends State<SplashScreen> {
  //INICIALIZAMOS LAS VARIABLES DE LA INFO QUE NOS DA EL PACKAGE GET_VERSION
  String _platformVersion = 'Unknown';
  String _projectVersion = '';
  String _projectCode = '';
  String _projectAppID = '';
  String _projectName = '';
  bool logeado = false;
  String uuid = "";

  @override
  void initState() {
    super.initState();

    initPlatformState(); //#0004

    Future.delayed(Duration(seconds: 6), () {
      //#005
      Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => App(), //#0006
          ));
    });
  }

Followed by App():

class App extends StatefulWidget {
  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  String uuid = "";

  @override
  void initState() {
    super.initState();
    uuid = CheckLogin().userData();

    NotificationService.instance.start(); //#0012
  }

  @override
  Widget build(BuildContext context) {
    return uuid != null ? MyNavigationBar() : Login();
  }

  @override
  void dispose() {
    super.dispose();
  }
}

And here you have CheckLogin():

class CheckLogin{
  final FirebaseAuth auth = FirebaseAuth.instance;

  String userData() {
    final User user = auth.currentUser;
    if (user !=null){
      final uid = user.uid;
      return uid;
    }
    else {
     return null;
    }

    ;
  }
}

And now you have Login():

class Login extends StatefulWidget {
  @override
  _LoginState createState() => _LoginState();
}

class _LoginState extends State<Login> {

  @override
  void initState() {

    super.initState();
  }

  @override
  void dispose() {

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {

    final authBloc = Provider.of<AuthBloc>(context, listen: false);

    return Scaffold(
        body: ListView(
          padding: EdgeInsets.only(top: 15.0),
          children: <Widget>[

            Container(
              height: MediaQuery.of(context).size.height * 0,
              decoration: BoxDecoration(
                  image: DecorationImage(
                      image: AssetImage('assets/images/top_bg.png'),
                      fit: BoxFit.fill)),
            ),
            Container(
              height: 180.0,
              decoration: BoxDecoration(
                image: DecorationImage(
                    image: AssetImage('assets/images/app_icon_trans.png')),
              ),
            ),
            StreamBuilder<String>(
                stream: authBloc.email,
                builder: (context, snapshot) {
                  return AppTextField(
                    isIOS: Platform.isIOS,
                    hintText: "email".tr(),
                    cupertinoIcon: CupertinoIcons.mail_solid,
                    materialIcon: Icons.email,
                    textInputType: TextInputType.emailAddress,
                    errorText: snapshot.error,
                    onChanged: authBloc.changeEmail,
                  );
                }),
            StreamBuilder<String>(
                stream: authBloc.password,
                builder: (context, snapshot) {
                  return AppTextField(
                    isIOS: Platform.isIOS,
                    hintText: "password".tr(),
                    cupertinoIcon: IconData(0xf4c9,
                        fontFamily: CupertinoIcons.iconFont,
                        fontPackage: CupertinoIcons.iconFontPackage),
                    materialIcon: Icons.lock,
                    obscureText: true,
                    errorText: snapshot.error,
                    onChanged: authBloc.changePassword,
                  );
                }),
            StreamBuilder<bool>(
                stream: authBloc.isValid,
                builder: (context, snapshot) {
                  return AppButton(
                    buttonText: "login".tr(),
                    buttonType: (snapshot.data == true)
                        ? ButtonType.LightBlue
                        : ButtonType.Disabled,
                    onPressed: authBloc.loginEmail,
                  );
                }),
            SizedBox(
              height: 6.0,
            ),
            Center(
              child: Text("o".tr(), style: TextStyles.suggestion),
            ),
            SizedBox(
              height: 6.0,
            ),
            Padding(
              padding: BaseStyles.listPadding,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[

                  AppSocialButton(
                    socialType: SocialType.Google,
                    onPressed: authBloc.signinGoogle,
                  ),

                ],
              ),
            ),
            Padding(
              padding: BaseStyles.listPadding,
              child: RichText(
                  textAlign: TextAlign.center,
                  text: TextSpan(
                      text: "nuevo".tr(),
                      style: TextStyles.body,
                      children: [
                        TextSpan(
                            text: "createaccount".tr(),
                            style: TextStyles.link,
                            recognizer: TapGestureRecognizer()
                              ..onTap =
                                  () => Navigator.pushNamed(context, '/signup'))
                      ])),
            ),

          ],
        ),
      );
    }
  }

When the user starts the app the first time, after the SplashScreen the app shows Login().

Then when the user makes the login, the app shows MyNavigationBar().

This part of the app is working fine. If the user closes the app, on the next start the app opens the SplashScreen and then MyNavigationBar(), as expected.

The issue I have is during the sign out procedure. There is a button to signout:

onTap: () async {
                    await _auth.signOut();

                    Navigator.pushAndRemoveUntil(
                        context,
                        MaterialPageRoute(builder: (context) => Login()),
                        (route) => false);
                  }

When the user taps on the button, the app shows Login(), but after making the login again, the app stays in login, only when making a new run of the app (using Run app from Android Studio without closing the app) then the app shows the SplashScreen again and then opens MyNavigationBar().

I guess there is a problem on some part of the code managing the state that is not working fine.


Solution 1: omar hatem

so my guess is because you are using two nested MaterialApp in the first one you define onGenerateRoute: Routes.materialRoutes, and the second one has them with null. I tried to figure out whats wrong with that but didn't find anything other than this

If home, routes, onGenerateRoute, and onUnknownRoute are all null, and builder is not null, then no Navigator is created.

from Flutter docs

probably when you make

Navigator.pushAndRemoveUntil(
                    context,
                    MaterialPageRoute(builder: (context) => Login()),
                    (route) => false);

it will pop everything except for the first MaterialApp it finds, in this case it will not remove the MaterialApp which doesn't have onGenerateRoute so when you call Navigator.pushNamed(context, '/signup')) nothing happens

my opinion is to remove MyApp since it does nothing and add the localization to the first MaterialApp

i.e

child: MaterialApp(
            title: "Mov-Map",
            debugShowCheckedModeBanner: false,
            localizationsDelegates: context.localizationDelegates,
            supportedLocales: context.supportedLocales,
            locale: context.locale,
            home: SplashScreen()
            onGenerateRoute: Routes.materialRoutes,
            theme: ThemeData(scaffoldBackgroundColor: Colors.white)))),