Notifications are an important tool used on the majority of Android & iOS applications, used to improve user experience, used to engage users with your application and much more. The Cloud Messaging module provides basic support for displaying and handling notifications.
Looking for an advanced local notifications library which integrates with FCM? Check out Notifee!
Displaying a Notification
The Firebase Cloud Messaging SDKs for Android and iOS allow for notifications to be displayed on devices when the application
is either quit or in the background. The Firebase Console, Firebase Admin SDKs and REST API all allow a notification
property to be attached to a message.
If an incoming message with this property exists, and the app is not currently visible (quit or in the background), a notification is displayed on the device. However, if the application is in the foreground, an event will be delivered containing the notification data and no visible notification will be displayed. See the Usage documentation to learn more about handling events.
Via Firebase Console
The Firebase Console provides a simple UI to allow devices to display a notification. Using the console, you can:
- Send a basic notification with custom text and images.
- Target applications which have been added to your project.
- Schedule notifications to display at a later date.
- Send recurring notifications.
- Assign conversion events for your analytical tracking.
- A/B test user interaction (called "experiments").
- Test notifications on your development devices.
The Firebase Console automatically sends a message to your devices containing a notification
property which is handled
by the React Native Firebase Cloud Messaging module. See Handling Interaction to learn about how
to support user interaction.
Via Admin SDKs
The various Firebase Admin SDKs allow you to send messages to your users. If these messages also contain notification options, the React Native Firebase Cloud Messaging module will automatically display these notifications.
For example, when using the firebase-admin
package in a Node.js environment
to send messages from a server, a notification
property can be added to the message payload:
await admin.messaging().sendMulticast({
tokens: [
/* ... */
], // ['token_1', 'token_2', ...]
notification: {
title: 'Basic Notification',
body: 'This is a basic notification sent from the server!',
imageUrl: 'https://my-cdn.com/app-logo.png',
},
});
The Cloud Messaging module will intercept these messages and if the notification
property is available, it will display
a notification on the device (if the app is not in the foreground). Messages sent with both a notification
and data
property
will display a notification and also trigger the onMessage
handlers (see Usage).
The different Admin SDKs available have similar implementation details on how to add a custom notification
property to
the FCM payload, however the Cloud Messaging module will handle all requests. To learn more, view the
Firebase Admin SDK documentation for your chosen admin SDK. For those using the
HTTP implementation, view the REST Cloud Messaging
reference.
Via REST
If you are unable to use a Firebase Admin SDK, Firebase also provides support for sending messages to devices via a POST request:
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data":{},
"notification":{
"body":"This is an FCM notification message!",
"title":"FCM Message"
}
}
}
To learn more about the REST API, view the Firebase documentation, and select the "REST" tab under the code examples.
Handling Interaction
When a user interacts with your notification by pressing on it, the default behavior is to open the application (since notifications via FCM only display when the application is in the background, the application will always open).
In many cases, it is useful to detect whether the application was opened by pressing on a notification (so you could open a specific screen for example). The API provides two APIs for handling interaction:
getInitialNotification
: When the application is opened from a quit state.onNotificationOpenedApp
: When the application is running, but in the background.
To handle both scenarios, the code can be executed during setup. For example, using React Navigation we can set an initial route when the app is opened from a quit state, and push to a new screen when the app is in a background state:
import React, { useState, useEffect } from 'react';
import { Linking, ActivityIndicator } from 'react-native';
import messaging from '@react-native-firebase/messaging';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
const NAVIGATION_IDS = ['home', 'post', 'settings'];
function buildDeepLinkFromNotificationData(data): string | null {
const navigationId = data?.navigationId;
if (!NAVIGATION_IDS.includes(navigationId)) {
console.warn('Unverified navigationId', navigationId)
return null;
}
if (navigationId === 'home') {
return 'myapp://home';
}
if (navigationId === 'settings') {
return 'myapp://settings';
}
const postId = data?.postId;
if (typeof postId === 'string') {
return `myapp://post/${postId}`
}
console.warn('Missing postId')
return null
}
const linking = {
prefixes: ['myapp://'],
config: {
initialRouteName: 'Home',
screens: {
Home: 'home',
Post: 'post/:id',
Settings: 'settings'
}
},
async getInitialURL() {
const url = await Linking.getInitialURL();
if (typeof url === 'string') {
return url;
}
//getInitialNotification: When the application is opened from a quit state.
const message = await messaging().getInitialNotification();
const deeplinkURL = buildDeepLinkFromNotificationData(message?.data);
if (typeof deeplinkURL === 'string') {
return deeplinkURL;
}
},
subscribe(listener: (url: string) => void) {
const onReceiveURL = ({url}: {url: string}) => listener(url);
// Listen to incoming links from deep linking
const linkingSubscription = Linking.addEventListener('url', onReceiveURL);
//onNotificationOpenedApp: When the application is running, but in the background.
const unsubscribe = messaging().onNotificationOpenedApp(remoteMessage => {
const url = buildDeepLinkFromNotificationData(remoteMessage.data)
if (typeof url === 'string') {
listener(url)
}
});
return () => {
linkingSubscription.remove();
unsubscribe();
};
},
}
function App() {
return (
<NavigationContainer linking={linking} fallback={<ActivityIndicator animating />}>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Post" component={PostScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
Quick Tip: On Android
you can test receiving remote notifications on the emulator but on iOS
you will need to use a real device as the iOS simulator does not support receiving remote notifications.
Getting a Device Token
To send messages to a device, you would need the FCM token for it, which you can get using the messaging().getToken()
method. An example is available on 'Notifee pages'.
await messaging().registerDeviceForRemoteMessages();
const token = await messaging().getToken();
// save the token to the db
Advanced Local Notifications
FCM provides support for displaying basic notifications to users with minimal integration required. If however you require more advanced notifications we recommend using our separate local notifications package 'Notifee'.
Notifee is free to use and fully open source.
Notifee - Android Features
- Advanced channel and group management.
- Custom appearance with HTML text styling, custom icons, badge support, colors and more.
- Behavior management such as custom sounds, vibration patterns, device notification light management and more.
- Displaying on-going Foreground Service Notifications for dealing with long-running background tasks.
- Advanced interaction handling with action buttons, quick reply features and more.
- Support for built in styling; Big Picture Style, Big Text Style, Inbox Style & Messaging Style notifications.
- Adding Progress Indicators & Timers to your notification.
Notifee - iOS Features
- Advanced Permission management.
- Behavior management such as custom sounds and critical notifications.
- Creating actions & categories.
To learn more about integrating FCM with Notifee, view the integration documentation.