How to implement Firebase Cloud Messaging (FCM) in Flutter (Android & iOS)
This is a comprehensive and easy to follow tutorial, explaining how to implement Firebase Cloud Messaging (FCM) in a Flutter application for both Android and iOS, covering foreground and background/terminated states. #Flutter #Firebase #FCM #FirebaseMessaging #PushNotifications #MobileDevelopment #CrossPlatformDevelopment #iOS #Android #Xcode #AppDevelopment #FlutterTips #flutter_local_notifications #flutter_messaging #FlutterCLI
Watch here, and make sure to follow our amazing developer Bohdan Samusko on YouTube:
This video is a comprehensive tutorial on how to implement Firebase Cloud Messaging (FCM) in a Flutter application for both Android and iOS, covering foreground and background/terminated states.
Summary of the tutorial
This is a comprehensive tutorial on how to implement Firebase Cloud Messaging (FCM) in a Flutter application for both Android and iOS, covering foreground and background/terminated states.
Here's a breakdown of the key steps (please note that the file names would make more sense when you watch the video, as the code is visible there):
- Firebase Project Setup:
- Create a new Firebase project (e.g., "Push notifications sample").
- Disable optional features like Gemini and Google Analytics for simplicity.
- Flutter Project Setup & Dependencies:
- Add necessary Flutter plugins to pubspec.yaml:
- firebase_core: For initializing Firebase.
- firebase_messaging: For handling FCM.
- flutter_local_notifications: For displaying notifications when the app is in the foreground (as FCM doesn't auto-display them in this state).
- Add necessary Flutter plugins to pubspec.yaml:
- Firebase CLI & FlutterFire Configuration:
- Ensure Firebase CLI is installed and logged in (firebase login).
- Activate FlutterFire CLI (dart pub global activate flutterfire_cli).
- Run flutterfire configure to link the Flutter app with the Firebase project, selecting Android and iOS platforms. This generates firebase_options.dart and platform-specific configuration files (GoogleService-Info.plist for iOS, google-services.json for Android).
- iOS APNs (Apple Push Notification service) Configuration:
- Go to the Apple Developer account.
- Navigate to "Certificates, Identifiers & Profiles" -> "Keys".
- Create a new APNs key, enabling "Apple Push Notifications service (APNs)".
- Name the key (e.g., "Test APNs key") and configure it for "Sandbox & Production".
- Download the generated .p8 key file.
- Go back to the Firebase console -> Project Settings -> Cloud Messaging.
- Under "Apple app configuration", upload the downloaded .p8 key file.
- Provide the Key ID and Team ID (obtained from the Apple Developer account).
- iOS Xcode Project Configuration:
- Open the iOS module of the Flutter project in Xcode (ios/Runner.xcworkspace).
- Select the "Runner" target, then "Signing & Capabilities".
- Add the "Push Notifications" capability.
- Addsthe "Background Modes" capability and enables "Remote notifications" within it.
- Crucially, for flutter_local_notifications on iOS: Modify AppDelegate.swift to import flutter_local_notifications and add specific code to didFinishLaunchingWithOptions to ensure iOS handles foreground notifications correctly by passing events to the Flutter plugin.
- Flutter Code Implementation:
- local_notifications_service.dart:
- Creates a service class (singleton pattern).
- Initializes FlutterLocalNotificationsPlugin.
- Sets up Android (AndroidInitializationSettings with a default icon like @mipmap/ic_launcher) and iOS (DarwinInitializationSettings requesting permissions for alert, badge, sound).
- Creates an init() method to initialize the plugin with platform settings and set up an onDidReceiveNotificationResponse callback.
- Creates an Android notification channel (AndroidNotificationChannel).
- Creates a showNotification() method to display local notifications using the plugin.
- firebase_messaging_service.dart:
- Creates a service class (singleton pattern).
- Creates an init() method that:
- Takes an instance of LocalNotificationsService.
- Handles retrieving and printing the FCM token (FirebaseMessaging.instance.getToken()).
- Listens for token refresh events (FirebaseMessaging.instance.onTokenRefresh).
- Requests notification permissions for iOS (FirebaseMessaging.instance.requestPermission()).
- Sets up a background message handler (FirebaseMessaging.onBackgroundMessage) which must be a top-level or static function.
- Listens for foreground messages (FirebaseMessaging.onMessage.listen) and uses the LocalNotificationsService to display them.
- Listens for messages that opened the app (FirebaseMessaging.onMessageOpenedApp.listen).
- Checks for an initial message that opened the app from a terminated state (FirebaseMessaging.instance.getInitialMessage()).
- main.dart:
- Makes main asynchronous.
- Ensures WidgetsFlutterBinding.ensureInitialized().
- Initializes Firebase (await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform)).
- Initializes LocalNotificationsService and FirebaseMessagingService.
- local_notifications_service.dart:
- Testing Notifications:
- Run the app on an iOS simulator (and implicitly Android would work similarly).
- Allow notification permissions when prompted.
- Copy the FCM token printed in the debug console.
- Go to Firebase Console -> Messaging -> "Create your first campaign" -> "Firebase Notification messages".
- Compose a notification (e.g., "Firebase Messaging", "Hello from Firebase!").
- Click "Send test message", paste the FCM token, and send.
- Foreground Test: The notification appears, handled by flutter_local_notifications.
- Close the app (send it to background/terminate it).
- Modify the notification title in Firebase (e.g., "Firebase Messaging Background").
- Send another test message.
- Background Test: The notification appears as a system notification. Tapping it opens the app.
