After a user successfully logins in and saving the state, I want to hide the login screen and just load the home screen, but I end up with the error
The following assertion was thrown building Navigator-[GlobalObjectKey _WidgetsAppState#6686e](dirty, dependencies: [UnmanagedRestorationScope, HeroControllerScope], state: NavigatorState#c7e9f(tickers: tracking 1 ticker)): 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 5070 pos 12: '': is not true.
What is the right way of hiding the login screen when the token is still valid, and just load the home screen?
my code
Main.dart
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'What',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
scaffoldBackgroundColor: Palette.scaffold,
),
// home: SignIn(),
routes: {
//Homepage and being controled by PagesProvider
'/': (context) => SignIn(),
'nav': (context) => NavScreen(),
// add all routes with names here
},
);
}
}
my signin.dart
class SignIn extends StatefulWidget {
const SignIn({Key key}) : super(key: key);
@override
_SignInState createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
ProgressDialog progressDialog;
MsalMobile msal;
bool isSignedIn = false;
bool isLoading = true;
@override
void initState() {
super.initState();
MsalMobile.create('assets/auth_config.json', authority).then((client) {
setState(() {
msal = client;
});
refreshSignedInStatus();
});
}
/// Updates the signed in state
refreshSignedInStatus() async {
bool loggedIn = await msal.getSignedIn();
if (loggedIn) {
isSignedIn = loggedIn;
if (isSignedIn) {
dynamic data = await handleGetAccount();
dynamic token = await handleGetTokenSilently();
dynamic result = token;
SharedPreferences sharedPreferences =
await SharedPreferences.getInstance();
sharedPreferences.get("username");
sharedPreferences.get("token");
print('access token (truncated): ${result.accessToken}');
Navigator.of(context).pop();
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => NavScreen(),
),
);
}
// Remaining code for navigation
}
}
/// Gets a token silently.
Future<dynamic> handleGetTokenSilently() async {
String authority = "https://login.microsoftonline.com/$TENANT_ID";
final result = await msal.acquireTokenSilent([SCOPE], authority);
if (result != null) {
// print('access token (truncated): ${result.accessToken}');
SharedPreferences sharedPreferences =
await SharedPreferences.getInstance();
sharedPreferences.setString("token", result.accessToken);
return result;
} else {
print('no access token');
return null;
}
}
/// Signs a user in
handleSignIn() async {
await msal.signIn(null, [SCOPE]).then((result) {
// ignore: unnecessary_statements
refreshSignedInStatus();
}).catchError((exception) {
if (exception is MsalMobileException) {
logMsalMobileError(exception);
} else {
final ex = exception as Exception;
print('exception occurred');
print(ex.toString());
}
});
}
logMsalMobileError(MsalMobileException exception) {
print('${exception.errorCode}: ${exception.message}');
if (exception.innerException != null) {
print(
'inner exception = ${exception.innerException.errorCode}: ${exception.innerException.message}');
}
}
/// Signs a user out.
handleSignOut() async {
try {
print('signing out');
await msal.signOut();
print('signout done');
refreshSignedInStatus();
} on MsalMobileException catch (exception) {
logMsalMobileError(exception);
}
}
/// Gets the current and prior accounts.
Future<dynamic> handleGetAccount() async {
// <-- Replace dynamic with type of currentAccount
final result = await msal.getAccount();
if (result.currentAccount != null) {
SharedPreferences sharedPreferences =
await SharedPreferences.getInstance();
sharedPreferences.setString("username", result.currentAccount.username);
//print(result.currentAccount.username);
return result.currentAccount;
} else {
print('no account found');
return null;
}
}
@override
Widget build(BuildContext context) {
progressDialog = ProgressDialog(context, type:ProgressDialogType.Normal, isDismissible: false, );
return MaterialApp(
home: new Scaffold(
body: Builder(
builder: (context) => Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Image.asset('assets/landing.webp',
fit: BoxFit.fill,
color: Color.fromRGBO(255, 255, 255, 0.6),
colorBlendMode: BlendMode.modulate),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 10.0),
Container(
width: 130.0,
child: Align(
alignment: Alignment.center,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0)),
color: Color(0xffffffff),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(
FontAwesomeIcons.microsoft,
color: Color(0xFF01A6F0),
),
// Visibility(
// visible: !isSignedIn,
SizedBox(width: 10.0),
Text(
'Sign in',
style: TextStyle(
color: Colors.black, fontSize: 18.0),
),
// child: RaisedButton(
// child: Text("Sign In"),
// onPressed: handleSignIn,
// ),
// ),
],
),
onPressed: () => {
progressDialog.show(),
handleSignIn(),
progressDialog.hide()
})),
)
],
),
],
),
),
));
}
}
you should Navigate to the homePage only if the login is successful
because Naviagation.Pop is Equal to the Back button and user can do it manually
here is a better approach :
in main.dart add this :
routes: {
Homepage and being controled by PagesProvider
'nav': (context) => NavScreen(),
'home': (context) => HomePage(),
// add all routes with names here
},
in your refreshSignedInStatus() :
remove this :
Navigator.of(context).pop();
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => NavScreen(),
),
);
add this :
Navigator.pushNamed(context, 'nav');
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.