FCM: How to bring the app from background to foreground? - flutter

I have an app in which I am using FCM (Firebase Cloud Messaging).
As given in the README, I've managed to get it all working and the event handlers for onResume, onMessage, onLaunch are all firing properly.
The onBackgroundMessage which I think is supposed to run whenever the notifications appear while the app is inactive, needs a top-level dart function.
I need this function to render a particular widget, say, IncomingCall. But this being a top-level function, the best I could think of, is to invoke the main():
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) {
main();
}
which then calls runApp(IncomingCall()) but even this is not working.
So how does one render a widget in Dart when the app is inactive?

Related

Flutter Local notifications - notification click is not working while the app in background

When application killed then notification click not working account to onSelectNotification and also big picture image notification not working when app in background.
flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: (action) {})
Handle background messages by registering a onBackgroundMessage handler. When messages are received, an isolate is spawned (Android only, iOS/macOS does not require a separate isolate) allowing you to handle messages even when your application is not running. try this:
#pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
await Firebase.initializeApp();
print("Handling a background message: ${message.messageId}");
}
void main() {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
follow full documentation here: https://firebase.google.com/docs/cloud-messaging/flutter/receive
There is no such thing as "in the background" with mobile devices. Mobile devices run one foreground app. When you "put it in the background" it is closed and a screenshot is kept to make you think it's "in the background". It's not. It's closed.
So it does not work when it's closed. That's normal. Because the app isn't running, it cannot execute code.
The app has first to be started again. To find out, whether your app was started by tapping a notification, you can use this line in your start up code:
final NotificationAppLaunchDetails notificationAppLaunchDetails =
await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
Source: Documentation
This way you can find out if your app was started from your notification and then act accordingly (for example by navigating to a different route depending on those details).

How to wait for a Flutter app to open before navigating to a particular page by clicking a scheduled notification?

I'm working on a Flutter project where I had to set a scheduled local notification that would fire everyday at 10 am. And, the user should be taken to a certain page of the app upon clicking the notification.
I've completed this part and the functionality works fine when the app is open and the user clicks on the notification.
But the problem arises when the app is closed and the notification is fired and the user clicks on the notification. It doesn't take the user to that certain page. I tried to modify the click handling function by making it an async function. But it doesn't work accordingly.
Can someone suggest me what to do now?
Create a notification handler.
Initialize your notification channel with high importance
Just before your app runs, before runApp(yourApp), create call a foregroundMessageHandler that you have initialized before the void main(){}
the foregroundMessageHandler should be a *TopMost initialization.
in the foregroundMessageHandler function, define the navigation behaviour
I don't know which library you are using for local notifcations. but if you are using flutter_local_notifications library check the link: https://pub.dev/packages/flutter_local_notifications
, you can check the data recived in selectNotification method and redirect the user to required page
void selectNotification(String payload) async {
if (payload != null) {
debugPrint('notification payload: $payload');
}
await Navigator.push(
context,
MaterialPageRoute<void>(builder: (context) => SecondScreen(payload)),
);
}
other libraries should have same functionality.

Flutter firebase messaging v9.0.0 - Not firing events

I have an app that was using firebase messaging 7.0.3 and all worked perfectly. But when I migrated to firebase messaging 9.0.0, the push notifications are not being handled.
I know that the app is correctly linked to firebase and cloud messaging because in background I see the push notification comming, the problem is when I click that notification the app don't handle this event. Also, when the app is in foreground, the event of receiving the notification is not being triggered.
Specifically, the functions FirebaseMessaging.onMessage and FirebaseMessaging.onMessageOpenedApp are not working. My code is:
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print("notification: message");
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print("notification: resume");
});
The prints are never called, and if I put some more code inside isn't executed too.
I also call FirebaseMessaging.getToken and I can get the token, plus when the app is in background I get the push notification, so is not a link problem with firebase. In the logs, when I receive the push I can see a message saying: Broadcast received for message. So I assumed that the push is arriving in all the occasions, and I am doing something wrong in the code.
I tested all cases in Android and iOS physical devices.
Someone know why this occurs?
I came across this exact same issue after migrating and upgrading to 9.0.0.
There is a minor issue with 9.0.0 plugin.
The fix can be found here:
https://github.com/FirebaseExtended/flutterfire/issues/4949
To cut a long story short, if you navigate to the definition of the factory
RemoteMessage.fromMap() Using Cmd+Click or Ctrl+Click while hovering over the RemoteMessage class with the mouse), in the return statement, change contentAvailable: map['contentAvailable'], to contentAvailable: map['contentAvailable']??false.
Notifications are now working for me again now.
This should work for you until the plugin is fixed.

Why is onTokenRefresh not firing?

I'm new to firebase messaging and flutter. According to the flutter firebase_messaging package docs, onTokenRefresh is fired when a new FCM token is generated. And according to Google's firebase docs there are two scenarios that triggers token generation:
When a new token is generated on initial app startup
Whenever an existing token is changed
Here is a simplified version of the main function of my application. After each execution, I delete the app from the emulator and the displayed token does indeed change. Despite this, onTokenRefresh is never fired and it should if my understanding of the documentation is correct.
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.instance.onTokenRefresh.listen((String token) {
print("New token: $token");
});
String token = await FirebaseMessaging.instance.getToken();
print("Token: $token");
//runApp(MyApp());
}
As I said, I'm new to flutter, dart and firebase messaging, is there something I'm fundamentally misunderstanding? Thanks.
So I think I figured it out. I noticed that sometimes, the onTokenRefresh does indeed fire. And I was wondering if it had something to do with how the flutter application is launched onto the emulator, in the sense that there is a race condition between when the token is generated and the listener attached.
To get the app to appear to start for the first time, I wiped the app data. Unfortunately this causes the flutter to automatically disconnect from the app which means I won't see the output of the print statement. So instead of trying to print when the token generation occurs, I assigned a value from the onTokenRefresh listener to a variable. I then updated a text widget with the value of the variable. And onTokenRefresh does indeed fire each time at start up if the app data has previously been wiped.

Flutter - myBackgroundMessageHandler never called in push notification

I am using firebase_messaging library with firebase for push notification in flutter. The documentation says that myBackgroundMessageHandler is called when the app is in background. But it has not happened.
I would like to format the title and the body of the notification before it is shown. I am getting notifications when the app is in the background but that particular method is not called. Currently it just shows the exact text sent by backend in title and body.
Is there something I have to do to enable(?) this method? I have it in my fcm.configure method:
_fcm.configure(
onBackgroundMessage: myBackgroundMessageHandler,
)
static Future<Map<String, dynamic>> myBackgroundMessageHandler(Map<dynamic, dynamic> message) async {
//some code here
return message;
}
Thanks in advance!
I had the same problem.
onBackgroundMessage apparently gets triggered only for data-messages.
See the difference here:
https://firebase.google.com/docs/cloud-messaging/concept-options
With FCM, you can send two types of messages to clients:
Notification messages, sometimes thought of as "display messages."
These are handled by the FCM SDK automatically.
Data messages, which
are handled by the client app.
In my case I had to remove the notification (subject, body etc), but also styling like bigpicture completely. Try sending only a data object.