[![Join the chat at https://gitter.im/evollu/react-native-fcm](https://badges.gitter.im/evollu/react-native-fcm.svg)](https://gitter.im/evollu/react-native-fcm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ## Installation - Run `npm install react-native-fcm --save` - Run `react-native link react-native-fcm` (RN 0.29.1+, otherwise `rnpm link react-native-fcm`) ## Android Configuration - Edit `android/build.gradle`: ```diff dependencies { classpath 'com.android.tools.build:gradle:2.0.0' + classpath 'com.google.gms:google-services:3.0.0' ``` - Edit `android/app/build.gradle`: ```diff apply plugin: "com.android.application" + apply plugin: 'com.google.gms.google-services' ``` - Edit `android/app/src/main/AndroidManifest.xml`: ```diff + + + + + + + + + + ... ``` ### Config for notification and `click_action` in Android 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: Edit `AndroidManifest.xml`: ```diff + + + + ``` Notes: - `launchMode="singleTop"` is to reuse MainActivity - replace `"fcm.ACTION.HELLO"` by the `click_action` you want to match And pass intent into package, edit `MainActivity.java`: - RN 0.28+: ```diff import com.facebook.react.ReactActivity; + import android.content.Intent; public class MainActivity extends ReactActivity { + @Override + public void onNewIntent (Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + } ``` - RN <= 0.27: ```diff import com.facebook.react.ReactActivity; + import android.content.Intent; public class MainActivity extends ReactActivity { + @Override + protected void onNewIntent (Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + } ``` Notes: - `@Override` is added to update intent on notification click ## IOS Configuration ### Pod approach: Make sure you have Cocoapods version > 1.0 Install the `Firebase/Messaging` pod: ``` cd ios && pod init pod install Firebase/Messaging ``` ### Non Cocoapod approach 1. Download the Firebase SDK framework from [Integrate without CocoaPods](https://firebase.google.com/docs/ios/setup#frameworks) 2. Follow the `README` to link frameworks (Analytics+Messaging) ### Shared steps Edit `AppDelegate.m`: ```diff + #import "Firebase.h" // if you are using Non Cocoapod approach + #import "RNFIRMessaging.h" //... - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //... + [FIRApp configure]; } + - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler { + [[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:notification]; + handler(UIBackgroundFetchResultNewData); + } ``` ### FCM config file In [firebase console](https://console.firebase.google.com/), you can get `google-services.json` file and place it in `android/app` directory and get `GoogleService-Info.plist` file and place it in `/ios/your-project-name` directory (next to your `Info.plist`) ## Usage ```javascript import FCM from 'react-native-fcm'; class App extends Component { componentDidMount() { FCM.requestPermissions(); // for iOS 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 leaking this.refreshUnsubscribe(); this.notificationUnsubscribe(); } } ``` ### Behaviour when sending `notification` and `data` payload through GCM - When app is not running when user clicks notification, notification data will be passed into `FCM.initialData` - When app is running in background (the tricky one, I strongly suggest you try it out yourself) - IOS will receive notificaton from `FCMNotificationReceived` event * if you pass `content_available` flag true, you will receive one when app is in background and another one when user resume the app. [more info](http://www.rahuljiresal.com/2015/03/retract-push-notifications-on-ios/) * if you just pass `notification`, you will only receive one when user resume the app. * you will not see banner if `notification->body` is not defined. - Android will receive notificaton from `FCMNotificationReceived` event * if you pass `notification` payload. it will receive data when user click on notification * if you pass `data` payload only, it will receive data when in background e.g. fcm payload looks like: ```json { "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 ```json { "fcm": {"action": "fcm.ACTION.HELLO"}, "extra": "juice" } ``` - iOS ```json { "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](http://stackoverflow.com/questions/33738848/handle-multiple-notifications-with-gcm)). ## Q & A #### My Android build is failing Try update your SDK and google play service #### I can't get notification when app is killed 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`. Use `notification` in the payload instead. #### App running in background doesn't trigger `FCMNotificationReceived` when receiving hybrid notification [Android] These is [an issue opened for that](https://github.com/google/gcm/issues/63). Behavior is not consistent between 2 platforms #### Android notification is showing a white icon Since Lollipop, the push notification icon is required to be all white, otherwise it will be a white circle. #### I am using Proguard You need to add this to your `android/app/proguard-rules.pro`: ``` # Google Play Services -keep class com.google.android.gms.** { *; } -dontwarn com.google.android.gms.** ``` #### Some features are missing Issues and pull requests are welcome. Let's make this thing better!