How to setup FCM Push Notification with React Native…
If you are new to firebase and FCM this article will be useful to setup FCM Push Notification with React Native application. We will be using react-native-firebase(doc: https://rnfirebase.io/docs/v5.x.x/getting-started) module to retrieve token for the push notifications.
Prerequisites
First, create the Firebase account and download the google-services.json
file from the console.
- Access your firebase account and go to the project settings from the top gear icon.
- Create an app if you don’t have it already.
- Go to the Cloud Messages section and add a server key
- Download the
google-services.json
file from the General Page(refer 2nd point). Copy the google-services.json to theandroid/app/
folder of your react-native project.
Configuring react-native-firebase modules
If you can visit the documentation you will be able to follow the steps. But I’m gonna add here the specific steps that you need to setup it in Android application.
1. Install the library
npm install --save react-native-firebase // or yarn add react-native-firebase
2. Add gradle dependency under android/app/build.gradle
dependencies { // ... implementation "com.google.android.gms:play-services-base:16.0.1" implementation "com.google.firebase:firebase-core:16.0.7" implementation "com.google.firebase:firebase-messaging:17.4.0" }
Check for the existing first two lines of the dependencies and choose the correct library for it. You can use following mvn repositories to find the correct version
When finding the peer version, try to match it with the release date since most are working properly within a particular period of releases.
3. Add the RNFirebaseMessagingPackage to your android/app/src/main/java/com/[app name]/MainApplication.java
// ... import io.invertase.firebase.RNFirebasePackage; import io.invertase.firebase.messaging.RNFirebaseMessagingPackage; // <-- Add this line public class MainApplication extends Application implements ReactApplication { // ... @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new RNFirebasePackage(), new RNFirebaseMessagingPackage() // <-- Add this line ); } }; // ... }
4. Update android manifest file.
<application ...> <service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <!-- For background messaging --> <service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" /> </application> //For RNFB versions less than 5.2.0 only; add the instance ID service: <application ...> <service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/> </intent-filter> </service> </application>
Finally try build the application with above configurations
Troubleshooting
Most of the time you will get an error like following.
The library com.google.android.gms:play-services-basement is being requested by various other libraries at [[15.0.1,15.0.1]], but resolves to 16.1.0.Disable the plugin and check your dependencies tree using ./gradlew :app:dependencies.
If you get the different version error and check whether you have strict versions in the android/build.gradle
def googlePlayServicesVersion = '15.0.1' configurations.all { resolutionStrategy { eachDependency { DependencyResolveDetails details -> if (requested.group == 'com.google.android.gms') { details.useVersion "$googlePlayServicesVersion" } Obsolete under new firebase if (requested.group == 'com.google.firebase') { details.useVersion "$googlePlayServicesVersion" } } } }
This will set the google.android.gms version to be strict to a defined version.
Comment it out if you want it to use the versions of your modules and use the module version defined of the the android/app/build.gradle file.
Still if you get this error add the following line to the bottom of the android/app/build.gradle
file. But I highly urge you not to do so. But it can be tolerated since there arent any mediator who controls the versions of the modules that we use. Maybe we should have something like that in future.
com.google.gms.googleservices.GoogleServicesPlugin.config.disableVersionCheck = true
Implementing FCM Push Notification with React Native.
Go to your codebase and add following.
import firebase, { Notification, RemoteMessage } from 'react-native-firebase'; // add following code to an appropriate place. // implement notifications as needed if (Platform.OS === 'android') { try { const res = await firebase.messaging().requestPermission(); const fcmToken = await firebase.messaging().getToken(); if (fcmToken) { logger.log('FCM Token: ', fcmToken); const enabled = await firebase.messaging().hasPermission(); if (enabled) { logger.log('FCM messaging has permission:' + enabled) } else { try { await firebase.messaging().requestPermission(); logger.log('FCM permission granted') } catch (error) { logger.log('FCM Permission Error', error); } } firebase.notifications().onNotificationDisplayed((notification: Notification) => { // Process your notification as required // ANDROID: Remote notifications do not contain the channel ID. You will have to specify this manually if you'd like to re-display the notification. logger.log('Notification: ', notification) }); this.notificationListener = firebase.notifications().onNotification((notification: Notification) => { logger.log('Notification: ', notification) }); } else { logger.log('FCM Token not available'); } } catch (e) { logger.log('Error initializing FCM', e); } }
Background Notifications
If you need to display background notifications, you will have to add following HeadlessTask on index.js
file of your codebase.
import { AppRegistry } from 'react-native'; import App from './App'; import firebase, { RemoteMessage } from 'react-native-firebase'; // Move to a proper place const handleFCMNotification = async (message: RemoteMessage) => { console.log('FCM OFFLINE: ', message); return Promise.resolve(); } AppRegistry.registerComponent('myapp', () => App);// your main app component // FCM background message task AppRegistry.registerHeadlessTask('RNFirebaseBackgroundMessage', () => PushNotificationService.handleFCMNotification);
How to Test
Go to your Firebase Console and go to the Cloud Messaging under Grow section.
Then select Send Your First Message.
Add test title and notification text, which is the message body. Click on Send Test Message
Add the token retrieved from the frontend logs when running your app.
Fill the other details and click on Review and Then Publish.
This message should be then appearing on the intended device as a notification.
Troubleshooting
You might get following error when requesting the token or any Firebase FCM Push Notification with React Native.
The [[DEFAULT]] firebase app has not been initialized!
Solved the issue by removing xmlns:tools="http://schemas.android.com/tools"
and tools:node="replace"
from AndroidManifest.xml. It should be two lines in separate places.
More
If you are into react native, feel free to check this tutorial on configuring AWS AppSync Graphql for react-native apps
Pingback: Android/iOS React-native heap limit allocation failed error()