I am trying to implement local Firebase notifications in background in Android with Flutter.
Following this tutorial, I was able to get my notifications successfully set up when the app is in foreground. But while the app is in background, I do see the local notifications, but also the original notifications sent by Firebase (which I do not see while the app is in foreground).
This is a problem. Since our server sends multiple notifications, and I am implementing android_local_notifications to filter through them, and show only selected ones though local notification channel.
This is my implementation:
void main() {
// Register local notification channel
static final AndroidNotificationChannel androidChannel =
AndroidNotificationChannel(
'android_local_notifications',
'Android Local Notifications',
description: 'Used to show foreground notifications on Android.',
importance: Importance.max,
);
static final AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('mipmap/ic_launcher');
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(androidChannel);
flutterLocalNotificationsPlugin.initialize(
InitializationSettings(android: initializationSettingsAndroid, iOS: null),
);
// set up on background
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
/// 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.
/// https://firebase.google.com/docs/cloud-messaging/flutter/receive
#pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// Initialize firebase
await Firebase.initializeApp();
// Creates a local notification
flutterLocalNotificationsPlugin.show(
notificationHashCode,
translatedTitleString,
translatedBodyString,
NotificationDetails(
android: AndroidNotificationDetails(
androidChannel.id,
androidChannel.name,
channelDescription: androidChannel.description,
),
),
);
}
Manifest:
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver"
android:exported="true" tools:replace="android:exported"/>
How do I get to hide the original Firebase pushes while the app is in background?
Related
We have implemented firebase notification in a flutter app running on android. Below is the function that we have defined for handling background messages
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
#pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
// 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.
print('Handling a background message ${message.messageId}'); }
below is the notification body that is being sent
{
"to" : "eYQ8cukfTzW:APA91b,
"data" : {
"body" : "Notification Body",
"title": "Notification Title",
"key_1" : "Value for key_1",
"key_2" : "Value for key_2"
}
}
We are using firebase_messaging: ^14.1.0
My call handler is above my main function
#pragma('vm:entry-point') //this is used for where indicates this function not removed while releasing
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
print('Handling a background message ${message.messageId}');
}
Inside my main.dar
I am calling this like this
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); //for handling background
And for foreground messages like this
FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( alert: true, badge: true, sound: true);
it works perfectly fine while the app is in the foreground. However, if the app is closed then the notification is not going to the background message handler
The notifications appear when the app is running. However, if the app is closed, the app does not catch any notifications. it seems like the background method does not get invoked when notifications are received. Can anyone please help how to fix this?
I'm handling FCM in my flutter app and i want only to receive one scheduled notification if my app is terminated and i don't want to receive it if app is working in the background now.
This is my code and when i'm testing i'm receiving this notification if my app is in background or is terminated.
Future<void> background_handler(RemoteMessage message) async {
await Firebase.initializeApp();
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: FirebaseOptions(apiKey:
"apikey", appId: "appid", messagingSenderId: "senderid", projectId: "projid"));
//handle msg in terminate case
RemoteMessage? message = await FirebaseMessaging.instance.getInitialMessage();
if(message != null){
PushNotification notification = new PushNotification(title:
message.notification?.title?? "Title",
body: message.notification?.body?? "Body", dataTitle: message.data["title"],
dataBody: message.data["body"] );
}
FirebaseMessaging.onBackgroundMessage(background_handler);
runApp(const MyApp());
}
How I can change this code to make app only receive this notification if it's terminated, or it's not possible to separate the background and terminated cases?
I don't think that's possible since onBackgroundMessage handles messages when the app is in both background and terminated state. Also, Flutter can only detect if the app is in background but not when it's terminated.
I have a flutter app that uses local notifications https://pub.dev/packages/flutter_local_notifications.
I have a notification that is set to a certain date :
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onDidReceiveNotificationResponse: (NotificationResponse response) async {
print("FOREGORUND");
},
onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
);
await flutterLocalNotificationsPlugin.zonedSchedule(
uid.hashCode,
title,
desc,
timez.TZDateTime.from(datex, timez.local),
NotificationDetails(
android: AndroidNotificationDetails(
'your channel id', 'your channel name',
channelDescription: 'your channel description',
actions: <AndroidNotificationAction>[
AndroidNotificationAction(
"CompleteID",
"Complete",
icon: DrawableResourceAndroidBitmap('complete_img'),
showsUserInterface: false,
cancelNotification: true,
),
],)
),
payload: uid,
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime);
When I click on the complete action from the notification, the app calls "notificationTapBackground" even if the app is in foreground, so from notificationTapBackground isolate thread i can' t call setstate inside my app.
I would like to be able to click on the complete action from the notification and have :
the app calls notificationTapBackground, if the app is in the background
the app calls onDidReceiveNotificationRespons, if the app is in the foreground
all with the parameter showsUserInterface: false, inside notification actions.
I am using Local Notifications for my app and it is working fine on my iPhone but when firing a Notification on my Android Simulator it is not showing the Notification on top of the screen but only the dot:
The Notification actually appears fine in the Notification Center:
I am making sure to init and I a calling instantNotification which looks like this:
Future initialize() async {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
AndroidInitializationSettings androidInitializationSettings =
AndroidInitializationSettings('app_icon');
IOSInitializationSettings iosInitializationSettings =
IOSInitializationSettings();
final InitializationSettings initializationSettings =
InitializationSettings(
android: androidInitializationSettings,
iOS: iosInitializationSettings);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
//Instant Notifications
Future instantNofitication() async {
var android = AndroidNotificationDetails('id', 'channel', 'description');
var ios = IOSNotificationDetails();
var platform = new NotificationDetails(android: android, iOS: ios);
await _flutterLocalNotificationsPlugin.show(
0,
'Demo instant notification',
'Tap to do something',
platform,
payload: 'Welcome to demo app',
);
}
What am I missing here?
You can try setting the importance level of the notification to a maximum with this line:
importance: Importance.max
which you add to the AndroidNotificationDetails class instance. This will tell to an Android OS that notification is important for the user and a heads-up display (a little popup) on top of the screen should be displayed for a few seconds.
I think that will solve your problem after reading an Android notification documentation
Adding on to #Antonio Valentic's answer, add the following properties to the AndroidNotificationDetails
importance: Importance.max,
priority: Priority.max,
fullScreenIntent: true,
enableVibration: true,
playSound: true
As quoted from the link:
The user's activity is in fullscreen mode (the app uses fullScreenIntent).
The notification has high priority and uses ringtones or vibrations
on devices running Android 7.1 (API level 25) and lower.
The notification channel has high importance on devices running Android 8.0 (API level 26) and higher.
I'm developing an application, related to Child Security, in Flutter.
A parent can request the child's application to send an Image or a 15 seconds Audio.
FCM is implemented and perfectly working fine when the application is running or in the background. When a notification received on Child's mobile application, the application moves to the relevant screen and performs the task.
But when the application is closed/terminated, it's not working. The notification is received, but the application doesn't start automatically. I have to click the notification, which I don't want to.
Can I achieve this, in Flutter? Something like WhatsApp or Facebook Messenger call feature?
What I have tried so far is, calling the main function on a notification received or runApp, but got no success.
void _firebaseMessagingBackgroundHandler(RemoteMessage message) {
main();
<------- and ------>
runApp(MaterialApp(home: ChildDashboard()));
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: CustomSplash(
imagePath: 'assets/images/logo.png',
backGroundColor: Colors.pink[50],
animationEffect: 'zoom-in',
logoSize: 1000,
home: sendToRelevantScreen(),
duration: 2500,
type: CustomSplashType.StaticDuration,
),
));
}