- Run
npm install react-native-fcm --save
- Run
rnpm link
Or you can combine 2 commands
- Run
rnpm install react-native-fcm --save
- In
android/build.gradle
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0'
classpath 'com.google.gms:google-services:3.0.0' // <- Add this line
- In
android/app/build.gradle
apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services' // <- Add this line
...
- In
android/app/src/main/AndroidManifest.xml
<application
android:theme="@style/AppTheme">
...
<service android:name="com.evollu.react.fcm.MessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service android:name="com.evollu.react.fcm.InstanceIdService" android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
...
To allow android to respond to click_action
, you need to define Activities and filter on specific intent. Since all javascript is running in MainActivity, you can have MainActivity to handle actions.
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:windowSoftInputMode="adjustResize"
android:launchMode="singleTop" <--add this line to reuse MainActivity
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter> <--add this line
<action android:name="fcm.ACTION.HELLO" /> <--add this line, name should match click_action
<category android:name="android.intent.category.DEFAULT" /> <--add this line
</intent-filter> <--add this line
</activity>
and pass intent into package, change MainActivity.java
import android.content.Intent; <--add this line next to the other imports
@Override <--add this line
protected void onNewIntent(Intent intent){ <--add this line
setIntent(intent); <--add this line to update intent on notification click
} <--add this line
@Override
protected List<ReactPackage> getPackages() {
...
new FIRMessagingPackage(getIntent()), <--add getIntent()
...
install pod 'Firebase/Messaging'
in AppDelegate.m add
#import "RNFIRMessaging.h"
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
....
[FIRApp configure]; <-- add this line
}
//add this method
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
[[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:notification];
handler(UIBackgroundFetchResultNoData);
}
In firebase console, you can get google-services.json
file and place it in android/app
directory and get googleServices-info.plist
file and place it in /ios
directory
import FCM from 'react-native-fcm';
...
componentWillMount() {
FCM.requestPermissions();
FCM.getFCMToken().then(token => {
console.log(token)
// store fcm token in your server
});
this.notificationUnsubscribe = FCM.on('notification', (notif) => {
// there are two parts of notif. notif.notification contains the notification payload, notif.data contains data payload
});
this.refreshUnsubscribe = FCM.on('refreshToken', (token) => {
console.log(token)
// fcm token may not be available on first load, catch it here
});
FCM.subscribeToTopic('/topics/foo-bar');
FCM.unsubscribeFromTopic('/topics/foo-bar');
}
componentWillUnmount() {
// prevent leak
this.refreshUnsubscribe();
this.notificationUnsubscribe();
}
...
-
When app is not running when user clicks notification, notification data will be passed into
-
FCM.initialAction
(containsclick_action
in notification payload -
FCM.initialData
(containsdata
payload if you send together with notification) -
When app is running in background
-
App will receive notificaton from
FCMNotificationReceived
event when user click on notification. e.g. fcm payload looks like{ "to":"some_device_token", "content_available": true, "notification": { "title": "hello", "body": "yo", "click_action": "fcm.ACTION.HELLO" }, "data": { "extra":"juice" } }
and event callback will receive as
///Android { fcm: {"action": "fcm.ACTION.HELLO"}, extra: "juice" } ///IOS { apns: {action_category: "fcm.ACTION.HELLO"}, extra: "juice" }
-
When app is running in foreground
-
IOS will receive notification and android won't (better not to do anything in foreground for hybrid and send a seprate data message.)
NOTE: it is recommend not to rely on data
payload for click_action as it can be overwritten. check this
Try update your SDK and google play service
If you send notification with data
only, you can only get the data message when app is in foreground or background. Killed app doesn't trigger FCMNotificationReceived. Seems that is how FCM works today
App running in background doesn't trigger FCMNotificationReceived
when receiving hybrid notification [Android]
These is an issue opened for that. Behavior is not consistent between 2 platforms
Issues and pull requests are welcomed. Let's make this thing better!