Flutter:how to delay the build method for sometime - flutter

I'm working on my project which includes signup and login and I'm also saving JSON web token (in the SharedPreferences) received from the API upon logged in or signed up.
I've created an async method which detects whether the the token is already saved inside sharedPreferences (so the user is authenticated and authorized to get access to home page without any need to enter username and password again)
when I use this method inside the initState() method of the landing page(which is in my case,the page that display the login form),
the landing page shows up for 1 second or less and then the token becomes available after the Future data returned by checkAuthentication becomes available ,
and then the user is redirected to the home page,
I want to make the landing page does not appear at all unless the token is not found
//by the way AuthData is just a custom class
Future<AuthData> checkAuthentication() async {
AuthData authData = new AuthData();
SharedPreferences preferences = await SharedPreferences.getInstance();
if(preferences.containsKey("token")){
authData.token = preferences.get("token");
return authData;
}
return null;
}
// initState method
#override
void initState() {
super.initState();
checkAuthentication().then((AuthData data){
if(data != null){
Navigator.of(context).pushNamedAndRemoveUntil("/home-page",
ModalRoute.withName(null));
} });
}

You can use setState
bool isLogin = false;
#override
void initState() {
super.initState();
checkAuthentication().then((AuthData data){
setState(() {
if(!data)
isLogin = true;
});
if(isLogin)
Navigator.of(context).pushNamedAndRemoveUntil("/home-page",
ModalRoute.withName(null));
});
}

Related

How to reset values in to default in flutter bloc when a user logout?

I have a application in which multiple users can login so when user logout and login another user without killing application the previous state should not be there
in provider I do something like this
void logOut() {
_orders = [];
_isGettingOrders = true;
_gettingOrdersError = false;
_gettingOrdersSuccess = false;
notifyListeners();
}
I write a logout function in every provider and call it in logout screen
how can I achieve this bloc

Flutter firebase auth login is not updating to home page

I am trying to update the home of MaterialApp widget depending on whether the user has sign up or not.
Below is the code inside the state of ``MaterialApp```
String? _userUid;
#override
void initState() {
FirebaseAuth.instance.authStateChanges().listen((user) {
//print('changed');
print(user?.uid);
updateUser(user?.uid);
});
super.initState();
}
void updateUser(String? USER_UID) {
setState(() {
_userUid = USER_UID;
});
}
Below is the code for the home property
home: _userUid == null ? const Onbaording2() : const HomeScreen(),
Somewhere inside the widget tree
final user = await _firebaseAuth.createUserWithEmailAndPassword(
email: email!,
password: password!,
);
After running the code above, there is a user created in firebase but the screen does not change.
Also the signOut works perfectly by signing me out when I use firebaseAuth.instance.signOut();
even if you change your variable it will not be redirected to the home screen because materialapp is only called when you first load or restart the app so rather than adding this condtion in home page or other way can be
#override
void initState() {
FirebaseAuth.instance.authStateChanges().listen((user) {
//print('changed');
print(user?.uid);
if(user == null){ navigate to onboarding }
else{ navigate to home page }
});
super.initState();
}

How to handle redirects from initState in Flutter

I am using the plugin flutter_local_notifications to show a user notifications on the app. I have managed to show the notifications on the app and the user can click on the notifications, the user will be redirected to see all pending items from the notification in a notification page. I have set the function to detect the onclick on initstate. The whole function and method to show notification I have implemented it on the homescreen.
#override
void initState() {
super.initState();
initPlatformState();
getNotifications();
NotificationApi.init(initScheduled: true);
init();
_configureSelectNotificationSubject(); //function to redirect to Notifications page
}
which goes to
void _configureSelectNotificationSubject() {
print("clicked is the notification");
NotificationApi.onNotifications.stream.listen((String? payload) async {
await Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => WANotifications(current: current)),
(Route<dynamic> route) =>
true);
});
}
The challenge am facing with this implementation is that when a user clicks to go to the home screen , the user gets redirected automatically to the notifications page from the home screen without his/her consent. The redirect should only occur when they click on the notifications.
How can I set the redirect to only occur when the user clicks the notification only and not when they click to go to home screen
You can achieve this with the help of didNotificationLaunchApp.
bool get didNotificationLaunchApp =>
notificationAppLaunchDetails?.didNotificationLaunchApp ?? false;
// Use here,
if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) {
selectedNotificationPayload = notificationAppLaunchDetails!.payload;
initialRoute = SecondPage.routeName;
}
Pl check full example here : https://pub.dev/packages/flutter_local_notifications/example
For non main file :
#override
void initState() {
super.initState();
localNotification(); // call below localNotification() here.
}
localNotification() async {
final NotificationAppLaunchDetails? notificationAppLaunchDetails =
await flutterLocalNotificationsPlugin!.getNotificationAppLaunchDetails();
if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) {
// redirect to new screen if true.
}
}

How to use Provider in a particular view/screen

I am using the Flutter provider package to manage all the states and separate the business logic from the UI part, and have all the API call present in the provider class that I need to call every time the user moves to that page.
But the issue is I don't want to hold the data even when the user moves to another screen that is the case when I declare provider in main.dart.
class _HomeScreenAppState extends State<HomeScreenApp> {
bool _isLoading;
int counter = 0;
String seller, user;
#override
void initState() {
_isLoading = true;
super.initState();
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
_fetchHomedetails();
}
Future<void> _fetchHomedetails() async {
await Provider.of<HomeDetailProvider>(context, listen: false)
.getEarnignStatus(context);}
}
I have used ChangeNotifierProvider(create:(context) =>HomeProvider(),
builder:(context) => HomeScreen()
But if there is any dialog (bottomsheet, alertdialog) which is using HomeProvider, the dialog cannot access the HomeProvider data present on its parent widget.

how is the best way to manage session and navigation in flutter web

I have 2 web pages on my proyect
I need to manage the user session. If the user is logged it appears the home page, and if the user is not logged it appears the login page.
I am using a provider to check the state of the session
#override
Widget build(BuildContext context) {
return Consumer<LoginGeneralNotifier>(
builder: (context, appGenaralNotifier, _) {
return appGenaralNotifier.getLogged()
? HomePage()
: LoginPage();
},
);
}
}
The problem is that the url does not change after I am logged
You may want to use Navigator.of(context).pushNamed(HomePageNamedRoute);
This can be done in initState as shown here:
Flutter Redirect to a page on initState
what I do is
I have created a class where I am keeping all the global variables
there I create a variable bool loginStatus;
and create two methods get and set for handling the value
and whenever login is successful I set the value to true loginStatus=true;
and on the new page in init() method I am checking the value of variable if value is false then throw the user to login page else continue
class GlobalValues{
static bool loginStatus;
static void setLoginStatus(bool val) {
loginStatus = val;
}
static bool getLoginStatus() {
return loginStatus == null ? false : loginStatus;
}
}
on login page if login is successful
GlobalValues.setLoginStatus(true);
on other class pages in init method
#override
void initState() {
if (GlobalValues.getLoginStatus()) {
// call your login page class here
//Navigator.of(context).pushNamed(LoginPageNamedRoute);
Navigator.pop(context);
}
super.initState();
}
Global variables are highly-frowned upon in the programming world (unless absolutely no other alternatives are available). Use user sessions instead. Check out FlutterSession. The package adds user session support in Flutter and is easy to use.
// Store value to session
await FlutterSession().set("token", myJWTToken);
// Retrieve item from session
dynamic token = await FlutterSession().get("token");