How to handle redirects from initState in Flutter - 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.
}
}

Related

flutter firebase onclick redirection when app is open

in my app firebase push notification is implemented.
on click event works when app is terminated.
but how to achieve notification on click of redirection when app is open.
class _Application extends State<Application> {
// It is assumed that all messages contain a data field with the key 'type'
Future<void> setupInteractedMessage() async {
// Get any messages which caused the application to open from
// a terminated state.
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
// If the message also contains a data property with a "type" of "chat",
// navigate to a chat screen
if (initialMessage != null) {
_handleMessage(initialMessage);
}
// Also handle any interaction when the app is in the background via a
// Stream listener
FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
}
void _handleMessage(RemoteMessage message) {
if (message.data['type'] == 'chat') {
Navigator.pushNamed(context, '/chat',
arguments: ChatArguments(message),
);
}
}
#override
void initState() {
super.initState();
// Run code required to handle interacted messages in an async function
// as initState() must not be async
setupInteractedMessage();
}

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();
}

Showing dialog when user loses internet connection in flutter

Is it possible to listen to the entire application in flutter and showing the dialog in case of loss of connection?
Yes it is possible. And you will need one package for this to work.
Internet Connection Checker
You can listen to the stream onConnectivityChanged from InternetConnectionChecker.
#override
void initState(){
super.initState();
var isDeviceConnected = false;
var subscription = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) async {
if(result != ConnectivityResult.none) {
isDeviceConnected = await InternetConnectionChecker().hasConnection;
if(!isDeviceConnected){
showDialog(
context,
// Your Dialog Here
);
}
}
});
}
Some things to consider here.
showDialog() needs a context, so put all of this code on the main
widget with MaterialApp.
You need to dismiss the dialog by yourself. You wont know if there is a dialog up or not at all. So, do it in your own discretion. Try not to pop() the MaterialApp itself.

Flutter:how to delay the build method for sometime

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));
});
}

How to change current page when app is inactive?

I need to redirect user to auth page when app is inactive for 5 minutes. I suppose using WidgetsBindingObserver. I detect when app is inactive for 5 minutes, but i don't know how to redirect user to auth page.
Here's part of my code:
#override
void initState() {
super.initState();
homeScreen = widget.homeScreen;
WidgetsBinding.instance.addObserver(this);
}
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() {
if (state == AppLifecycleState.paused) {
Future.delayed(Duration(seconds: 3), () {
setState(() {
// navigate to auth page
});
});
}
});
}
You can use the Navigator:
Navigator.push(context,
MaterialPageRoute(builder: (context) => AuthPage()));
You don't need redirect an app in 5 minutes, you can redirect it when user want to navigate into page (or to do some action) which needed to be authenticated, just log last action timestamp into SharedPreferences and check this timestamp on every needed-auth action.