README.md 6.49 KB
Newer Older
Libin Lu's avatar
init  
Libin Lu committed
1 2 3
## Installation

- Run `npm install react-native-fcm --save`
Libin Lu's avatar
Libin Lu committed
4
- Run `rnpm link`
Libin Lu's avatar
Libin Lu committed
5

Libin Lu's avatar
Libin Lu committed
6
Or you can combine 2 commands
Ashwin Preetham Lobo's avatar
Ashwin Preetham Lobo committed
7
- Run `rnpm install react-native-fcm`
Libin Lu's avatar
init  
Libin Lu committed
8

9
## Android Configuration
Libin Lu's avatar
init  
Libin Lu committed
10 11 12 13

- In `android/build.gradle`
```gradle
dependencies {
Libin Lu's avatar
Libin Lu committed
14 15
classpath 'com.android.tools.build:gradle:2.0.0'
classpath 'com.google.gms:google-services:3.0.0' // <- Add this line
Libin Lu's avatar
init  
Libin Lu committed
16 17 18 19 20 21 22 23 24
```

- In `android/app/build.gradle`
```gradle
apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services' // <- Add this line
...
```

Libin Lu's avatar
Libin Lu committed
25
- In `android/app/src/main/AndroidManifest.xml`
Libin Lu's avatar
init  
Libin Lu committed
26 27 28

```
<application
Libin Lu's avatar
Libin Lu committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
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>
...
Libin Lu's avatar
init  
Libin Lu committed
44
```
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
### 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.
```xml
<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
```java
Yann Leflour's avatar
Yann Leflour committed
66 67
import android.content.Intent;                                            <--add this line next to the other imports

68 69 70 71 72 73 74
// Add this line to update intent on notification click
@Override
// in RN <= 0.27 you may need to use `protected void onNewIntent (Intent intent) {`
public void onNewIntent (Intent intent) {
  super.onNewIntent(intent);
    setIntent(intent);
}       
75

76
// Add package
77 78 79
@Override
    protected List<ReactPackage> getPackages() {
    ...
80
      new FIRMessagingPackage(getIntent()),                               // <-- add getIntent()
81 82
    ...
```
Libin Lu's avatar
init  
Libin Lu committed
83

84
## IOS Configuration
Libin Lu's avatar
init  
Libin Lu committed
85 86

install pod 'Firebase/Messaging'
Libin Lu's avatar
Libin Lu committed
87 88 89 90 91
NOTE: make sure cocoapods version > 1.0
```
cd ios && pod init
pod install Firebase/Messaging
```
Libin Lu's avatar
init  
Libin Lu committed
92 93 94

in AppDelegate.m add
```
Libin Lu's avatar
Libin Lu committed
95
#import "RNFIRMessaging.h"
Libin Lu's avatar
Libin Lu committed
96
...
Libin Lu's avatar
init  
Libin Lu committed
97

Libin Lu's avatar
Libin Lu committed
98 99 100
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
....
101
  [FIRApp configure]; <-- add this line
Libin Lu's avatar
Libin Lu committed
102
}
Libin Lu's avatar
init  
Libin Lu committed
103

Libin Lu's avatar
Libin Lu committed
104
//add this method
105 106 107
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler {
  [[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:notification];
  handler(UIBackgroundFetchResultNoData);
Libin Lu's avatar
init  
Libin Lu committed
108 109 110 111 112 113 114
}
```


### 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 `googleServices-info.plist` file and place it in `/ios` directory

Libin Lu's avatar
Libin Lu committed
115
## Usage
Libin Lu's avatar
init  
Libin Lu committed
116 117

```javascript
Goran Gajic's avatar
Goran Gajic committed
118 119 120 121 122 123 124 125 126 127 128 129
  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
    });
130 131
    this.refreshUnsubscribe = FCM.on('refreshToken', (token) => {
      console.log(token)
Goran Gajic's avatar
Goran Gajic committed
132 133
      // fcm token may not be available on first load, catch it here
    });
Libin Lu's avatar
Libin Lu committed
134 135 136
    
    FCM.subscribeToTopic('/topics/foo-bar');
    FCM.unsubscribeFromTopic('/topics/foo-bar');
Goran Gajic's avatar
Goran Gajic committed
137 138 139 140 141 142 143 144
  }

  componentWillUnmount() {
    // prevent leak
    this.refreshUnsubscribe();
    this.notificationUnsubscribe();
  }
  ...
Libin Lu's avatar
init  
Libin Lu committed
145 146
```

147
### Behaviour when sending `notification` and `data` payload through GCM
Libin Lu's avatar
Libin Lu committed
148 149 150 151 152
- When app is not running when user clicks notification, notification data will be passed into 
 - `FCM.initialAction`(contains `click_action` in notification payload
 - `FCM.initialData` (contains `data` payload if you send together with notification)

- When app is running in background
Libin Lu's avatar
Libin Lu committed
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
 - 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"
    }
    ```
182

Libin Lu's avatar
Libin Lu committed
183
- When app is running in foreground
184
 - IOS will receive notification and android **won't** (better not to do anything in foreground for hybrid and send a seprate data message.)
185

Libin Lu's avatar
Libin Lu committed
186
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)
187

Libin Lu's avatar
init  
Libin Lu committed
188
## Q & A
Libin Lu's avatar
Libin Lu committed
189
#### My android build is failing
Libin Lu's avatar
Libin Lu committed
190
Try update your SDK and google play service
191
#### I can't get notification when app is killed
Libin Lu's avatar
Libin Lu committed
192
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
Libin Lu's avatar
Libin Lu committed
193
#### App running in background doesn't trigger `FCMNotificationReceived` when receiving hybrid notification [Android]
194 195
These is [an issue opened for that](https://github.com/google/gcm/issues/63). Behavior is not consistent between 2 platforms
#### It is missing some features
Libin Lu's avatar
Libin Lu committed
196
Issues and pull requests are welcomed. Let's make this thing better!
Libin Lu's avatar
init  
Libin Lu committed
197