Learn how to implement push notifications in your Flutter app using Firebase Cloud Messaging (FCM). This comprehensive guide covers setup, handling notifications, sending messages, and best practices.
Push notifications are a crucial component of modern mobile applications, providing a direct line of communication between your app and its users. Firebase Cloud Messaging (FCM) is a powerful tool that allows you to send notifications and messages across different platforms, including Android, iOS, and the web. In this section, we will explore how to integrate FCM into your Flutter app, handle notifications, and implement best practices for effective messaging.
Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably deliver messages at no cost. With FCM, you can notify a client app that new email or other data is available to sync. You can send notifications to drive user re-engagement and retention. FCM provides a reliable and battery-efficient connection between your server and devices that allows you to deliver and receive messages and notifications on iOS, Android, and the web at no cost.
Setting up FCM in your Flutter app involves several steps, including adding the necessary dependencies, configuring your Android and iOS projects, and initializing FCM in your app.
firebase_messaging
PackageTo start using FCM in your Flutter app, you need to add the firebase_messaging
package to your project. This package provides the necessary tools to handle FCM notifications.
Open your pubspec.yaml
file and add the firebase_messaging
dependency:
dependencies:
firebase_messaging: ^14.2.5
Run the following command to install the package:
flutter pub get
For Android, you need to configure your project to use Firebase services.
Add google-services.json
: Download the google-services.json
file from your Firebase project settings and place it in the android/app/
directory.
Update AndroidManifest.xml
: Add the necessary permissions and services to your AndroidManifest.xml
file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:name=".MyApplication"
android:label="app_name"
android:icon="@mipmap/ic_launcher">
<service
android:name="com.google.firebase.messaging.FirebaseMessagingService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<category android:name="com.example.app"/>
</intent-filter>
</receiver>
</application>
</manifest>
Apply the Google Services Plugin: In your android/build.gradle
file, add the Google services classpath:
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.3.10'
}
}
Then, apply the plugin in your android/app/build.gradle
file:
apply plugin: 'com.google.gms.google-services'
For iOS, the setup involves configuring your Xcode project to handle push notifications.
Add GoogleService-Info.plist
: Download the GoogleService-Info.plist
file from your Firebase project settings and add it to your Xcode project. Ensure that it is included in the target’s build settings.
Enable Push Notifications and Background Modes: In your Xcode project, navigate to the Signing & Capabilities tab and enable Push Notifications and Background Modes. Under Background Modes, check Remote notifications.
Request Permissions: Ensure your app requests notification permissions from the user. This is crucial for iOS devices.
To receive notifications, your app must request permission from the user. This is particularly important for iOS, where users must explicitly grant permission for notifications.
Use the following code to request notification permissions:
FirebaseMessaging messaging = FirebaseMessaging.instance;
await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
This code requests permission for various types of notifications, such as alerts, badges, and sounds.
Once your app is set up to receive notifications, you need to handle them appropriately. This involves listening for incoming messages and responding to them.
To handle incoming messages while the app is in the foreground, use the onMessage
stream:
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Received message: ${message.notification?.title}');
// Handle the message
});
This listener will be triggered whenever a message is received while the app is in the foreground.
For Android, you need to implement a background message handler to process messages when the app is not in the foreground:
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print('Handling a background message: ${message.messageId}');
}
void main() {
WidgetsFlutterBinding.ensureInitialized();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
This handler will be called whenever a message is received while the app is in the background or terminated.
There are several ways to send notifications using FCM, including the Firebase Console and programmatically using Cloud Functions.
The Firebase Console provides a simple interface for sending test messages to your app:
For more advanced use cases, you can send notifications programmatically using Firebase Cloud Functions. This allows you to trigger notifications based on events in your app, such as a new message being added to a Firestore collection.
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendPushNotification = functions.firestore.document('messages/{messageId}')
.onCreate((snapshot, context) => {
const messageData = snapshot.data();
const payload = {
notification: {
title: 'New message',
body: messageData.text,
},
};
return admin.messaging().sendToTopic('all', payload);
});
This function listens for new documents in the messages
collection and sends a notification to all subscribed users.
FCM allows you to manage subscriptions to topics, enabling you to send targeted messages to groups of users.
You can subscribe users to topics and send messages to all devices subscribed to a particular topic:
await FirebaseMessaging.instance.subscribeToTopic('all');
This code subscribes the current device to the all
topic, allowing it to receive messages sent to this topic.
Each device that registers with FCM receives a unique token. You can use these tokens to send targeted messages to specific devices.
String? token = await FirebaseMessaging.instance.getToken();
print('FCM Token: $token');
Store these tokens in your database to send personalized messages to individual users.
When a user clicks on a notification, you may want to navigate them to a specific screen in your app. You can handle this using the onMessageOpenedApp
stream:
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('Notification clicked!');
// Navigate to specific screen
});
This listener will be triggered whenever the app is opened from a notification click.
To make the most of push notifications, consider the following best practices:
To reinforce your understanding of FCM, try implementing push notifications in your app. Follow these steps:
By completing this exercise, you’ll gain hands-on experience with FCM and be better prepared to implement push notifications in your own projects.