Flutter apps do NOT show system notifications by default when using Firebase Messaging.
To display notifications both in foreground and background, you must combine:
✔ FirebaseMessaging
✔ FlutterLocalNotificationsPlugin
✔ Background message handler
Here is the full flow of how your code works.
main() — Initialize Firebase and Register Background Handler
R:\firebase\firebase\lib\main.dart
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(const MyApp());
}
👉 Simple Explanation
Prepares Flutter for async operations.
Initializes Firebase services.
Registers a background message handler for notifications received when app is killed or minimized.
Launches the Flutter app.
2️⃣ Background Handler — Runs When App Is Closed/Terminated
R:\firebase\firebase\lib\main.dart
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
print(message.notification!.title.toString());
}
👉 Simple Explanation
Called when notification arrives while app is closed/background.
Must be a top-level function.
Initializes Firebase inside the background isolate.
You can trigger local notification from here too (if needed).
3️⃣ initState() — Setup Permission, Token, Listeners, and Local Notification System
R:\firebase\firebase\lib\home_screen.dart
@override
void initState() {
super.initState();
_notificationServices.requestNotificationPermission();
_notificationServices.listenToTokenRefresh();
_notificationServices.getDeviceToken().then((value) { print(value); });
_notificationServices.initLocalNotifications(); // VERY IMPORTANT
_notificationServices.firebaseInit();
_notificationServices.handleNotificationClick(context);
}
👉 Simple Explanation
R:\firebase\firebase\lib\notification_services.dart
initLocalNotifications() — Setup Plugin + Notification Channel
void initLocalNotifications() async {
const AndroidInitializationSettings androidInitializationSettings =
AndroidInitializationSettings('@mipmap/ic_launcher');
const DarwinInitializationSettings iosInitializationSettings =
DarwinInitializationSettings();
const InitializationSettings initializationSettings = InitializationSettings(
android: androidInitializationSettings,
iOS: iosInitializationSettings,
);
await _flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (response) {},
);
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel_v2',
'High Importance Notifications',
description: 'Channel for important notifications',
importance: Importance.max,
);
await _flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
}
👉 Simple Explanation
R:\firebase\firebase\lib\notification_services.dart
firebaseInit() — Listen for Foreground Notifications
void firebaseInit() {
FirebaseMessaging.onMessage.listen((message) {
print(message.notification!.title.toString());
print(message.notification!.body.toString());
showNotification(message);
});
}
👉 Simple Explanation
Runs when the app is open
Firebase receives notification
Immediately calls showNotification() to show system-level notification
Because FCM does NOT show foreground notifications automatically
6️⃣ showNotification() — Show System Notification
R:\firebase\firebase\lib\notification_services.dart
Future<void> showNotification(RemoteMessage message) async {
const AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails(
'high_importance_channel',
'High Importance Notifications',
channelDescription: 'Channel for important notifications',
importance: Importance.high,
priority: Priority.high,
icon: '@mipmap/ic_launcher',
);
const DarwinNotificationDetails darwinNotificationDetails =
DarwinNotificationDetails(
presentAlert: true,
presentBadge: true,
presentSound: true,
);
const NotificationDetails notificationDetails = NotificationDetails(
android: androidNotificationDetails,
iOS: darwinNotificationDetails,
);
await _flutterLocalNotificationsPlugin.show(
0,
message.notification?.title ?? 'Notification',
message.notification?.body ?? '',
notificationDetails,
);
}
👉 Simple Explanation
Top comments (0)