-
Notifications
You must be signed in to change notification settings - Fork 4k
firebase_messaging: Normal Push Notifications appear silently or not at all when the flutter app is terminated #2603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi @royibernthal |
Hi @TahaTesser The issue is on both iOS and Android. flutter doctor -v on the machine that compiles for android
I have a different machine for compiling ios, I can provide flutter doctor for that a bit later. There are no errors there though, is there other info you'd like to see there?
MainActivity.kt
android/build.gradle
android/app/build.gradle
I'm not sure how I could post a minimal code sample to reproduce the problem without creating a separate app on both flutter and firebase and testing it on many devices, and that'd be a huge task. Correct me if I'm wrong. |
Same issue I am having currently |
I have got the same problem. Push notifications show instantly on one iOS device (iPhone 5c, 10.3.3) and not at all if app is in background/terminated on other (iPhone 6S, 13.5). App was installed from the same archive through diawi in debug mode. On iPhone 6S onMessage() is called if app is in foreground or after resuming app. It works fine both foreground and background on any Android I tested it on. I won't be able to post flutter run --verbose because I'm working on commercial product. There is too much information reviled there and it is too long to anonymize it. If some can publish that kind of logs you can run
|
I am also experiencing the same issue on Android. When the app is in the foreground, notifications are handled in the |
Try to remove all notification attributes from the payload of send requests and use only the data attribute with default information like title and body. Maybe this will work. Something like this: HTTP v1 version
Legacy version
|
Wouldn't omitting the notification key result in a data-only notification which by definition will not be visually displayed to the user? Have you tried that? |
Yes, here is working. After remove the notification attribute you can use the plugin flutter_local_notifications to show a big picture notification in place, for example. But I haven't tested this on iOS. |
Are you calling flutter_local_notifications in firebase_messaging's onBackgroundMessage? Also, shouldn't firebase_messaging just work on its own out of the box? I feel like it shouldn't be this complicated to receive push notifications. |
Here is my files: NotificationsHandler.dart
Application.java
FirebaseCloudMessagingPluginRegistrant.java
|
Got it. So yeah, you're doing exactly that :) You're calling flutter_local_notifications in firebase_messaging's onBackgroundMessage. |
Any update? |
Still researching and testing this to no avail. I'm hoping one of the plugin creators / moderators will step in at some point. |
Any update from the team, please? |
having the same issue. I also tried pushing notifications from firebase console(FCM) but cannot get the notifications when the app is terminated. |
On android you have to make sure you're setting up notification channels on the device and then sending push notifications to those channels, either from your backend or frontend (though frontend is not a good practice). I personally decided to move the whole project to OneSignal, it's free and it handles everything for me without any headaches, plus normal customer support. |
moving the whole project now could be very difficult for me. On the tutorials i never seen anything about setting up notification channels on the device. I believe its something with my code. |
The migration was actually very easy. Well, that's a big part of the problem, I had to dig deep in order to understand what was wrong. Maybe something is wrong with your code as you say, but there's a good chance that your code is okay and you're just missing this piece of the puzzle, which is hardly mentioned anywhere for some reason. Anyway, these are my 2 cents as someone who's been struggling with this for a long time :) |
When app is in foreground, and background i receive the notifications perfectly. But when the app is completely terminated i don't. Cannot be with data or notification because i am trying using the Firebase Console: Cloud Messaging, Compose notification, but only when the app is foreground or in stacks not terminated. I followed all instructions from the firebase read me and some tutorials. Android Manifest:
android/app/build.gradle android/build.gradle When i push the notification when the app is in background (not terminated but in stack). Flutter doctor: [✓] Flutter (Channel stable, v1.17.5, on Mac OS X 10.14.6 18G103, locale en-TZ) [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3) [✓] Xcode - develop for iOS and macOS (Xcode 11.3.1) [✓] Android Studio (version 3.5) [✓] VS Code (version 1.46.1) [✓] Connected device (1 available) • No issues found! |
@braysonjohn148 I'm having exactly the same issue. Did you manage to solve your issue? If so, i'd be really eager to know how if you mind sharing! |
Hi all, The problem related to Android is that I had a device that doesn't allow notifications to work in the background, and it's solved by turning on some options in the device itself. the option is Allow running in background. The problems related to iOS is that for some reason I needed to add rows to Up to now, everything works fine. but this doesn't mean I solved the issue for all devices because, as you know, I don't have all available devices to test on. I hope it gets fixed for you guys. Thanks |
That's great, thank you for sharing! :) But.... |
Yea, it's true. I'd like to know if there is any other possible solution. |
same issue here ! |
Guys, I'm ashamed to say this, but for me, my test Droid device was running under "no disturb mode", so everything was just going to control center, no sound, no vibration, no pop ups. |
This worked for me! : AndroidManifest.xml
App.kt
|
Any luck? |
Not sure if this is the same but throwing this in to help others who have the same issue , for me I had the notification shows onMessage and onResume, however the onLaunch only shows notification in control, tapping on that opens the app only when terminated,
|
same issue here ! |
Finally, I found a workaround for notification when the app is killed or terminated 1). I just added a new file called package [com].[yourdomain];
import io.flutter.app.FlutterApplication;
public class App extends FlutterApplication {
@Override
public void onCreate() {
super.onCreate();
}
}
<application
android:name=".App"
...
> Run the application again and the notifications working correctly with the app terminated or killed I hope this can help you too. |
I also implemented that. But still got the problem of not receiving notification when app was killed completely |
Issue still appearing on firebase_messaging 8.0.0-dev.8. Only on Android though. |
any update??? |
I Really can't see how this could solve anything here. |
So after 1year of continuous searching for the solution to that problem, researched al lot, talked to many developers. It has NO solution eventually. It totally depends on the manufacturer of mobile phone. |
I found the solution for my problem, which was: notifications appear silently ON ANDROID when the app is in the background or terminated. The key solution can be found here. I will copy the instructions and a small reproducible example here in case the link brakes. Instructions
The main idea is the following:
So we need to create a high importance channel through the flutter_local_notifications package.
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.', // description
importance: Importance.max,
);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel); Once created, we can now update FCM to use our own channel rather than the default FCM one. To do this, open the android/app/src/main/AndroidManifest.xml file for your FlutterProject project. Add the following meta-data schema within the application component: <meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" /> Reproductible example
main.dart import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
FirebaseMessaging messaging = FirebaseMessaging.instance;
print(await messaging.getToken());
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.', // description
importance: Importance.max,
);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Got a message whilst in the foreground!');
print('Message data: ${message.data}');
if (message.notification != null) {
print('Message also contained a notification: ${message.notification}');
}
});
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
}
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print("Handling a background message: ${message.messageId}");
}
Future selectNotification(String payload) {
print("selectNotification. payload: $payload");
}
Future onDidReceiveLocalNotification(int id, String title, String body, String payload) {
print("onDidReceiveLocalNotification. payload: $payload");
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Title'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
} pubspec.yaml name: flutter_test_fcm
description: A new Flutter application.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
firebase_core: "^0.5.3"
firebase_messaging: "^8.0.0-dev.11"
flutter_local_notifications: ^3.0.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="lulupointu.flutter_test_fcm">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="flutter_test_fcm"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" />
</application>
</manifest> Beware that you also need to initialize firebase and place the google-services.json in /android/app If you use flutterEmbedding v2 no need to do anything with the Application.java, otherwise refer to the documentation (not tested however) Hopes this helps you as much as this helped me, I was searching for a solution for 6 month! |
Finally I fixed it with update plugin version firebase_messaging to 8.0.0-dev.10. Here is my body FCM.
It's working in background and terminated mode on iOS. I'm just following step by step in firebase.flutter.dev. In this video I'm used flutter_local_notification to show local notification when received data from FCM. I'm tested on real device iPhone 6S iOS 14. Hopefully it's working for all of you. flutter doctor -v
pubspec.yaml
main.dart import 'dart:io';
import 'dart:isolate';
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:isapp/core/util/method_channel_helper.dart';
import 'app.dart';
import 'config/base_url_config.dart';
import 'config/flavor_config.dart';
import 'core/util/notification_handler.dart';
import 'core/util/shared_preferences_manager.dart';
import 'injection_container.dart' as di;
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
debugPrint('Handling a background message: ${message.messageId}');
debugPrint('Background message contained data: ${message.data}');
var androidNotificationDetails = AndroidNotificationDetails(
'0',
'0',
'0',
importance: Importance.high,
priority: Priority.high,
);
var iosNotificationDetails = IOSNotificationDetails();
var notificationDetails = NotificationDetails(android: androidNotificationDetails, iOS: iosNotificationDetails);
var localNotification = FlutterLocalNotificationsPlugin();
await localNotification.show(0, 'title local', 'description local', notificationDetails);
}
void triggerReminderAttendanceDevelopment() async {
final now = DateTime.now();
final isolateId = Isolate.current.hashCode;
print("start [$now] trigger reminder attendance! isolate=${isolateId} function='$triggerReminderAttendanceDevelopment'");
var notificationHandler = NotificationHandler();
await notificationHandler.initReminderAttendance();
notificationHandler.doTriggerReminderAttendance();
print("end [$now] trigger reminder attendance! isolate=${isolateId} function='$triggerReminderAttendanceDevelopment'");
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
debugPrint('onMessage');
debugPrint('Message data: ${message.data}');
if (message.notification != null) {
debugPrint('Message also contained a notification: ${message.notification}');
debugPrint('Message also contained a title: ${message.notification.title}');
debugPrint('Message also contained a body: ${message.notification.body}');
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
debugPrint('onMessageOpenedApp');
debugPrint('Message data: ${message.data}');
if (message.notification != null) {
debugPrint('Message also contained a notification: ${message.notification}');
debugPrint('Message also contained a title: ${message.notification.title}');
debugPrint('Message also contained a body: ${message.notification.body}');
}
});
await FirebaseMessaging.instance.requestPermission();
final baseUrlConfig = BaseUrlConfig();
FlavorConfig(
flavor: Flavor.DEVELOPMENT,
/*colorPrimary: Color(0xFFF8F9FD),
colorPrimaryDark: Color(0xFFF8F9FD),
colorPrimaryLight: Color(0xFFF8F9FD),*/
colorPrimary: Colors.green,
colorAccent: Colors.green,
values: FlavorValues(
baseUrlFakeJsonEndpoint: baseUrlConfig.baseUrlDevelopmentFakeJsonEndpoint,
baseUrlAuthEndpoint: baseUrlConfig.baseUrlDevelopmentAuthEndpoint,
baseUrlEmployeeEndpoint: baseUrlConfig.baseUrlDevelopmentEmployeeEndpoint,
baseUrlAttendanceEndpoint: baseUrlConfig.baseUrlDevelopmentAttendanceEndpoint,
baseUrlRequestEndpoint: baseUrlConfig.baseUrlDevelopmentRequestEndpoint,
baseUrlNotificationEndpoint: baseUrlConfig.baseUrlDevelopmentNotificationEndpoint,
baseUrlSettingEndpoint: baseUrlConfig.baseUrlDevelopmentSettingEndpoint,
baseUrlGeneralEndpoint: baseUrlConfig.baseUrlDevelopmentRootEndpoint,
baseUrlPanelEndpoint: baseUrlConfig.baseUrlDevelopmentPanelEndpoint,
baseUrlPayrollEndpoint: baseUrlConfig.baseUrlDevelopmentPayrollEndpoint,
),
);
await di.init();
final sharedPreferencesManager = di.sl<SharedPreferencesManager>();
if (sharedPreferencesManager.isKeyExists(SharedPreferencesManager.keyDomainApi)) {
var domainApi = sharedPreferencesManager.getString(SharedPreferencesManager.keyDomainApi);
FlavorConfig.instance.values.baseUrlAuthEndpoint = domainApi + '' + BaseUrlConfig().prefixAuthEndpoint;
FlavorConfig.instance.values.baseUrlEmployeeEndpoint = domainApi + '' + BaseUrlConfig().prefixEmployeeEndpoint;
FlavorConfig.instance.values.baseUrlAttendanceEndpoint = domainApi + '' + BaseUrlConfig().prefixAttendanceEndpoint;
FlavorConfig.instance.values.baseUrlNotificationEndpoint = domainApi + '' + BaseUrlConfig().prefixNotificationEndpoint;
FlavorConfig.instance.values.baseUrlRequestEndpoint = domainApi + '' + BaseUrlConfig().prefixRequestEndpoint;
FlavorConfig.instance.values.baseUrlPayrollEndpoint = domainApi + '' + BaseUrlConfig().prefixPayrollEndpoint;
}
WidgetsBinding.instance.addPostFrameCallback((_) async {
final methodChannelHelper = di.sl<MethodChannelHelper>();
if (Platform.isAndroid) {
await methodChannelHelper.initializeStetho();
}
});
var triggerReminderAttendanceId = 0;
if (Platform.isAndroid) {
await AndroidAlarmManager.initialize();
}
runApp(
EasyLocalization(
supportedLocales: [
Locale('en', 'US'),
Locale('id', 'ID'),
],
path: 'assets/translations',
fallbackLocale: Locale('en', 'US'),
child: App(),
),
);
if (Platform.isAndroid) {
await AndroidAlarmManager.periodic(
const Duration(hours: 1),
triggerReminderAttendanceId,
triggerReminderAttendanceDevelopment,
);
}
}
|
You can use the new dependency of firebase: Add settings for setup fcm:
You can add default sound at notification json :
|
I'm going to close this issue as we're now on version |
My flutter doctor is perfect.
I'm using firebase-admin on nodejs to send push notifications to users:
https://firebase.google.com/docs/admin/setup
I'm using firebase_messaging 6.0.13 on flutter:
https://pub.dev/packages/firebase_messaging
I'm trying to send a push notification with the highest priority on both android and ios.
On my development devices it works like a charm both when the app is in the background and when it's terminated.
I'm receiving push notifications that visibly pop and make a sound 100% of the time, on both android and ios.
The issue is on other devices -
If the app is in the background, I can sometimes see an actual push notification visibly pop, and make a sound as it should. Sometimes not.
If the app is terminated, a push notification is received - but it doesn't visibly pop nor make a sound, I can only see it if I scroll down the menu from the top of the screen, it's listed as a received push notification.
Sometimes the notification is not receieved at all.
I tried to change the priority of notifications from my app to high on the actual device as well, but it didn't change anything.
My users keep complaining that they're not receiving push notifications - I'm guessing they either actually don't receieve them or simply don't see them since they're recieved silently as I described above.
I literally have no idea what's going on and why it doesn't work as it should on devices other than my own development devices.
Any ideas?
The text was updated successfully, but these errors were encountered: