- Cloud Messaging
- Data messaging on android
- Android Notification & Data Messages From App Server Using Firebase Cloud Messaging
- Table of Contents
- Firebase Cloud Messaging Message Types
- Notification message in JSON format
- Data message in JSON format
- Notification and data message in JSON format
- Handling FCM Messages in Android
- Android Project Set up — Client of FCM
- Sending Messages from App Server to Firebase Cloud Messaging Server
- Getting access token
- Adding access token to http request header
- Creating and sending JSON message
- Android Firebase Cloud Messaging Example
- Notification message
- Data message
- Sending FCM Message from App Server Example
- AndroidManifest
- FirebaseMessagingService
- JobService
Cloud Messaging
Installation and getting started with Cloud Messaging.
This module requires that the @react-native-firebase/app module is already setup and installed. To install the «app» module, view the Getting Started documentation.
iOS requires further configuration before you can start receiving and sending messages through Firebase. Read the documentation on how to setup iOS with Firebase Cloud Messaging.
Use of the sendMessage() API and it’s associated listeners requires a custom XMPP server. Read the documentation on how to Messaging with XMPP.
If you’re using an older version of React Native without auto-linking support, or wish to integrate into an existing project, you can follow the manual installation steps for iOS and Android.
What does it do
React Native Firebase provides native integration of Firebase Cloud Messaging (FCM) for both Android & iOS. FCM is a cost free service, allowing for server-device and device-device communication. The React Native Firebase Messaging module provides a simple JavaScript API to interact with FCM.
The module also provides basic support for displaying local notifications, to learn more view the Notifications documentation.
iOS — Requesting permissions
iOS prevents messages containing notification (or ‘alert’) payloads from being displayed unless you have received explicit permission from the user.
To learn more about local notifications, view the Notifications documentation.
This module provides a requestPermission method which triggers a native permission dialog requesting the user’s permission:
The permissions API for iOS provides much more fine-grain control over permissions and how they’re handled within your application. To learn more, view the advanced iOS Permissions documentation.
On Android, you do not need to request user permission. This method can still be called on Android devices; however, and will always resolve successfully.
FCM messages can be sent to real Android/iOS devices and Android emulators (iOS simulators however do not handle cloud messages) via a number of methods (see below). A message is simply a payload of data which can be used however you see fit within your application.
Common use-cases for handling messages could be:
- Displaying a notification (see Notifications).
- Syncing message data silently on the device (e.g. via AsyncStorage ).
- Updating the application’s UI.
To learn about how to send messages to devices from your own server setup, view the Server Integration documentation.
Depending on the devices state, incoming messages are handled differently by the device and module. To understand these scenarios, it is first important to establish the various states a device can be in:
State | Description |
---|---|
Foreground | When the application is open and in view. |
Background | When the application is open, however in the background (minimised). This typically occurs when the user has pressed the «home» button on the device or has switched to another app via the app switcher. |
Quit | When the device is locked or application is not active or running. The user can quit an app by «swiping it away» via the app switcher UI on the device. |
The user must have opened the app before messages can be received. If the user force quits the app from the device settings, it must be re-opened again before receiving messages.
Depending on the contents of the message, it’s important to understand both how the device will handle the message (e.g. display a notification, or even ignore it) and also how the library sends events to your own listeners.
The device state and message contents determines which handler will be called:
Foreground | Background | Quit | |
---|---|---|---|
Notification | onMessage | setBackgroundMessageHandler | setBackgroundMessageHandler |
Notification + Data | onMessage | setBackgroundMessageHandler | setBackgroundMessageHandler |
Data | onMessage | setBackgroundMessageHandler (see below) | setBackgroundMessageHandler (see below) |
In cases where the message is data-only and the device is in the background or quit, both Android & iOS treat the message as low priority and will ignore it (i.e. no event will be sent). You can however increase the priority by setting the priority to high (Android) and content-available to true (iOS) properties on the payload.
On iOS in cases where the message is data-only and the device is in the background or quit, the message will be delayed until the background message handler is registered via setBackgroundMessageHandler, signaling the application’s javascript is loaded and ready to run.
To learn more about how to send these options in your message payload, view the Firebase documentation for your FCM API implementation.
The device state and message contents can also determine whether a Notification will be displayed:
Foreground | Background | Quit | |
---|---|---|---|
Notification | Notification: ❌ | Notification: ✅ | Notification: ✅ |
Notification + Data | Notification: ❌ | Notification: ✅ | Notification: ✅ |
Data | Notification: ❌ | Notification: ❌ | Notification: ❌ |
Foreground state messages
To listen to messages in the foreground, call the onMessage method inside of your application code. Code executed via this handler has access to React context and is able to interact with your application (e.g. updating the state or UI).
For example, the React Native Alert API could be used to display a new Alert each time a message is delivered’
The remoteMessage property contains all of the information about the message sent to the device from FCM, including any custom data (via the data property) and notification data. To learn more, view the RemoteMessage API reference.
If the RemoteMessage payload contains a notification property when sent to the onMessage handler, the device will not show any notification to the user. Instead, you could trigger a local notification or update the in-app UI to signal a new notification.
Background & Quit state messages
When the application is in a background or quit state, the onMessage handler will not be called when receiving messages. Instead, you need to setup a background callback handler via the setBackgroundMessageHandler method.
To setup a background handler, call the setBackgroundMessageHandler outside of your application logic as early as possible:
The handler must return a promise once your logic has completed to free up device resources. It must not attempt to update any UI (e.g. via state) — you can however perform network requests, update local storage etc.
The remoteMessage property contains all of the information about the message sent to the device from FCM, including any custom data via the data property. To learn more, view the RemoteMessage API reference.
If the RemoteMessage payload contains a notification property when sent to the setBackgroundMessageHandler handler, the device will have displayed a notification to the user.
When an incoming message is «data-only» (contains no notification option), both Android & iOS regard it as low priority and will prevent the application from waking (ignoring the message). To allow data-only messages to trigger the background handler, you must set the «priority» to «high» on Android, and enable the content-available flag on iOS. For example, if using the Node.js firebase-admin package to send a message:
For iOS specific «data-only» messages, the message must include the appropriate APNs headers as well as the content-available flag in order to trigger the background handler. For example, if using the Node.js firebase-admin package to send a «data-only» message to an iOS device:
View the Sending Notification Requests to APNs documentation to learn more about APNs headers.
These options can be applied to all FCM messages. View the Server Integration documentation to learn more about other available SDKs.
Background Application State
Although the library supports handling messages in background/quit states, the underlying implementation on how this works is different on Android & iOS.
On Android, a Headless JS task (an Android only feature) is created that runs separately to your main React component; allowing your background handler code to run without mounting your root component.
On iOS however, when a message is received the device silently starts your application in a background state. At this point, your background handler (via setBackgroundMessageHandler ) is triggered, but your root React component also gets mounted. This can be problematic for some users since any side-effects will be called inside of your app (e.g. useEffects , analytics events/triggers etc). To get around this problem, you can configure your AppDelegate.m file (see instructions below) to inject a isHeadless prop into your root component. Use this property to conditionally render null («nothing») if your app is launched in the background:
To inject a isHeadless prop into your app, please update your AppDelegate.m file as instructed below:
- For projects that use react-native-navigation (or if you just don’t want to mess with your launchProperties) you can use the getIsHeadless method (iOS only) from messaging like so:
On Android, the isHeadless prop will not exist.
Topics are a mechanism which allow a device to subscribe and unsubscribe from named PubSub channels, all managed via FCM. Rather than sending a message to a specific device by FCM token, you can instead send a message to a topic and any devices subscribed to that topic will receive the message.
Topics allow you to simplify FCM server integration as you do not need to keep a store of device tokens. There are however some things to keep in mind about topics:
- Messages sent to topics should not contain sensitive or private information. Do not create a topic for a specific user to subscribe to.
- Topic messaging supports unlimited subscriptions for each topic.
- One app instance can be subscribed to no more than 2000 topics.
- The frequency of new subscriptions is rate-limited per project. If you send too many subscription requests in a short period of time, FCM servers will respond with a 429 RESOURCE_EXHAUSTED («quota exceeded») response. Retry with exponential backoff.
- A server integration can send a single message to multiple topics at once. This however is limited to 5 topics.
To learn more about how to send messages to devices subscribed to topics, view the Send messages to topics documentation.
Subscribing to topics
To subscribe a device, call the subscribeToTopic method with the topic name (must not include «/»):
Unsubscribing to topics
To unsubscribe from a topic, call the unsubscribeFromTopic method with the topic name:
Messaging can be further configured to provide more control over how FCM is handled internally within your application.
Auto Registration (iOS)
React Native Firebase Messaging automatically registers the device with APNs to receive remote messages. If you need to manually control registration you can disable this via the firebase.json file:
Once auto-registration is disabled you must manually call registerDeviceForRemoteMessages in your JavaScript code as early as possible in your application startup;
Firebase generates an Instance ID, which FCM uses to generate a registration token and which Analytics uses for data collection. When an Instance ID is generated, the library will upload the identifier and configuration data to Firebase. In most cases, you do not need to change this behavior.
If you prefer to prevent Instance ID auto-generation, disable auto initialization for FCM and Analytics:
To re-enable initialization (e.g. once requested permission) call the messaging().setAutoInitEnabled(true) method.
Background handler timeout (Android)
On Android, a background event sent to setBackgroundMessageHandler has 60 seconds to resolve before it is automatically canceled to free up device resources. If you wish to override this value, set the number of milliseconds in your config:
Notification Channel ID
On Android, any message which displays a Notification use a default Notification Channel (created by FCM called «Miscellaneous»). This channel contains basic notification settings which may not be appropriate for your application. You can change what Channel is used by updating the messaging_android_notification_channel_id property:
Creating and managing Channels is outside of the scope of the React Native Firebase library, however external libraries such as Notifee can provide such functionality.
On Android, any messages which display a Notification do not use a color to tint the content (such as the small icon, title etc). To provide a custom tint color, update the messaging_android_notification_color property with a Android color resource name.
The library provides a set of predefined colors corresponding to the HTML colors for convenience, for example:
Note that only predefined colors can be used in firebase.json . If you want to use a custom color defined in your application resources, then you should set it in the AndroidManifest.xml instead.
To create advanced custom local notifications in React Native; check out our free and open source Notifee library.
Источник
Data messaging on android
Android Notification & Data Messages From App Server Using Firebase Cloud Messaging
December 13, 2017
If your Android app relies on app servers for data and functionality, instead of android app contacting app server at a specified regular intervals, server can notify events or data changes to android using Firebase cloud messaging (FCM).
This way of app servers notifying client or android apps has advantages compared to client contacting app server at a regular intervals. It reduces the use of android device resources including computing power and consumption of network bandwidth as communication between server and client happens only when there is a change in data or an occurrence of an event at server.
Table of Contents
Firebase Cloud Messaging Message Types
Firebase Cloud Messaging supports two types of messages, notification message and data message. The difference between them is that with data message you can send your own data elements in the message where as with notification message you have to use predefined elements.
As names suggest, notification message type is used to send notifications which will be displayed as notifications in the notification bar. FCM automatically handles notification messages and your app can also process it and customize it. Data message type is used to send data to client. Your app has to process it and take further action. There is restriction of 4kb on the size of message that can be sent to client.
Notification message in JSON format
Data message in JSON format
Notification and data message in JSON format
Note that in the data message, only name and value pairs are allowed under data element, meaning data element can’t have hierarchical data or JSON array.
App server can send a generic message to multiple clients using Firebase topic. Client apps which listen to the topic will get the message sent by the app server. In this post, the example shows how to send messages to a topic from server app and how client apps can register to a topic and handle the messages.
Using FCM, app server can send messages to a specific client or device using firebase generated registration key. To know how to send user or device specific message, please read sending device specific message from app server to FCM server and handling the message on android.
Handling FCM Messages in Android
Notification messages are handled automatically when receiving android app is in background and notification is displayed. On taping the notification, app’s launcher activity is started.
If notification needs to be displayed when receiving app is in foreground, the app needs to provide FirebaseMessagingService service implementing its callback onMessageReceived to process notification messages.
To handle the data messages in foreground and background, app needs to provide FirebaseMessagingService service implementing its callback onMessageReceived. Data can be retrieved from RemoteMessage object passed to onMessageReceived method.
If message contains both data and notification and app is in foreground, onMessageReceived callback is called. If message contains both data and notification and app is in background, notification is displayed in notification bar and data is passed as extras in the intent to launcher activity.
Android Project Set up — Client of FCM
To make your android app as client of firebase cloud messaging server to handle and process messages, you need to follow below steps.
- Login to Firebase console.
- Add project to Firebase by clicking add project link on main screen of Firebase console.
- To install Firebase SDK, go to project overview section in Firebase console, click add-Firebase to android project and follow steps to generate google-services.json. Download the file and save it in your project under app folder.
- Add below entry to bottom of app level gradle build file.
- Add below entry to project level gradle build file in dependencies element.
- Add Firebase cloud messaging library to app level build file.
- Enable Firebase cloud messaging API in Google developers console.
- Create android service extending FirebaseMessagingService and implementing onMessageReceived, see example below to know how to handle and process messages.
- Add the service to mainfest file.
Sending Messages from App Server to Firebase Cloud Messaging Server
Firebase cloud messaging server delivers to client app the message sent from the app server. App server can send message to FCM server using various protocols. Below example app I created shows how to send messages to FCM server from app server using HTTP v1 protocol.
Authentication and authorization of the app server to use firebase service can be done using short-lived access token. In order for your app server code to get the access token, it needs private key associated with a service account which is either owner or editor.
To get private key in Firebase console, go to settings, then service accounts and click Generate New Private Key. The Json file contain key gets downloaded. You need to store it securely.
To get access token using the private key in your app server code, you need to use Google API Client library. Below are the maven and gradle dependencies which you need to add to your app server project.
Getting access token
GoogleCredential can be used to get access token using private key downloaded from firebase console.
Adding access token to http request header
You can use any http library to send message request to FCM server. Http request header should contain access token.
Creating and sending JSON message
Android Firebase Cloud Messaging Example
I’ll show the use of Firebase cloud messaging using an example app. The app displays coupons in recycler view retrieved from SQLite database using ROOM. When latest coupons are available, app server sends notification and data messages to FCM server. The android app receives and processes the messages, stores latest coupons data in SQLite database on the device and displays notifications. Since LiveData is used, as data changes in SQLite database, change will be reflected in UI.
Notification message
Data message
Sending FCM Message from App Server Example
AndroidManifest
FirebaseMessagingService
JobService
Since log running task can’t be run in FirebaseMessagingService, firebase job scheduler is used to process FCM data messages.
Источник