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.
CodePudding user response:
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)))),
