Firebase Cloud Messaging (FCM) is a free cross-platform messaging solution that lets you deliver push notifications and data messages to your client app. While the documentation distinguishes between “notification messages” and “data messages”, it is not always clear how the two types are handled by the client.
As a wrapper on top of the Web Push API, the Firebase Messaging library provides “notification messages” as a convenience that handles the details of displaying push notifications to your users. FCM can also be used without them, as you are free to use data messages instead and utilize the Web Push API as you see fit.
A message is considered a notification if it contains a
click_action key is used by the Firebase SDK to decide what to do when the notification is clicked. Without it, clicking the notification will lead nowhere.
A data message does not have the
notification key, but contains a
data key instead:
Because it lacks a
notification key, the above message must be handled manually by your app. The Firebase documentation recommends that you always add a
notification key so that you don’t need to handle the displaying of the message yourself. If you want to add arbitrary data to a notification, it’s perfectly valid to include a notification key and a data key; Firebase will still treat it as a notification message and display it, and the extra data can be handled (manually) by your app.
A message sent by FCM will be handled in one or two places depending on its type: in your service worker by the callback passed to
setBackgroundMessageHandler(), and in your client code by the callback passed to
onMessage is always called when your app is running in the foreground (when the browser window and tab is in focus), both when receiving notification messages and data messages. The callback is invoked with the message
payload which you can read and handle as you’d like.
import firebase from 'firebase';
onBackgroundMessageHandler is called when your app is running in the background and the message does not contain a
notification key. In other words, this handler is only for data messages.
// In your service worker
Because the background handler is not called when you send a notification message, you cannot use it to customize the message’s behavior. The way to do that is to omit the
notification key and implement everything yourself, including click actions, inside the
What happens if your app receives a notification message while it is running in the background? The notification is displayed and neither handler will run. But, if you click on the notification, the custom
data payload (remember, you can always include both a
notification key and a
payload key) is sent to the
onMessage handler. The
notification key, though, is removed from the payload. This is all handled by the Firebase SDK.
It is also worth noting that notifications sent through the Firebase Console will indeed contain a
notification key and can therefore not be intercepted by
The relationship between message types and handlers can be summarized in a table:
|App in foreground||App in background|
|Notification message||onMessage||notification is displayed; onMessage runs when clicked|