README.md 6.54 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 5 6
- Run `rnpm link`
Or you can combine 2 commands
- Run `rnpm install react-native-fcm --save`
Libin Lu's avatar
init  
Libin Lu committed
7

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

- In `android/build.gradle`
```gradle
dependencies {
Libin Lu's avatar
Libin Lu committed
13 14
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
15 16 17 18 19 20 21 22 23
```

- 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
24
- In `android/app/src/main/AndroidManifest.xml`
Libin Lu's avatar
init  
Libin Lu committed
25 26 27

```
<application
Libin Lu's avatar
Libin Lu committed
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
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
43
```
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
### 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
@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()
    ...
```
Libin Lu's avatar
init  
Libin Lu committed
76

77
## IOS Configuration
Libin Lu's avatar
init  
Libin Lu committed
78 79 80 81 82

install pod 'Firebase/Messaging'

in AppDelegate.m add
```
Libin Lu's avatar
Libin Lu committed
83
#import "RNFIRMessaging.h"
Libin Lu's avatar
Libin Lu committed
84
...
Libin Lu's avatar
init  
Libin Lu committed
85

Libin Lu's avatar
Libin Lu committed
86 87 88 89 90
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
....
[FIRApp configure]; <-- add this line
}
Libin Lu's avatar
init  
Libin Lu committed
91

Libin Lu's avatar
Libin Lu committed
92
//add this
Libin Lu's avatar
init  
Libin Lu committed
93
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification {
Libin Lu's avatar
Libin Lu committed
94 95 96
[[NSNotificationCenter defaultCenter] postNotificationName: FCMNotificationReceived
object:self
userInfo:notification];
Libin Lu's avatar
init  
Libin Lu committed
97 98 99

}

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


### 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
113
## Usage
Libin Lu's avatar
init  
Libin Lu committed
114 115 116

```javascript

117
import {DeviceEventEmitter} from 'react-native';
Libin Lu's avatar
init  
Libin Lu committed
118 119 120
var FCM = require('react-native-fcm');

componentWillMount() {
Libin Lu's avatar
Libin Lu committed
121
FCM.requestPermissions();
Libin Lu's avatar
Libin Lu committed
122 123
FCM.getFCMToken().then(data => {
  console.log(data.token)
Libin Lu's avatar
Libin Lu committed
124 125 126 127 128
//store fcm token in your server
});
this.fcmNotifLsnr = DeviceEventEmitter.addListener('FCMNotificationReceived', (notif) => {
//there are two parts of notif. notif.notification contains the notification payload, notif.data contains data payload
});
Libin Lu's avatar
Libin Lu committed
129 130
this.fcmTokenLsnr = DeviceEventEmitter.addListener('FCMTokenRefreshed', (data) => {
  console.log(data.token)
Libin Lu's avatar
Libin Lu committed
131 132
//fcm token may not be available on first load, catch it here
});
Libin Lu's avatar
init  
Libin Lu committed
133 134 135
}

componentWillUnmount() {
Libin Lu's avatar
Libin Lu committed
136 137 138
//prevent leak
this.fcmNotifLsnr.remove();
this.fcmTokenLsnr.remove();
Libin Lu's avatar
init  
Libin Lu committed
139 140 141 142 143
}

}
```

144
### Behaviour when sending `notification` and `data` payload through GCM
Libin Lu's avatar
Libin Lu committed
145 146 147 148 149
- 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
150 151 152 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
 - 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"
    }
    ```
179

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

Libin Lu's avatar
Libin Lu committed
183
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)
184

Libin Lu's avatar
init  
Libin Lu committed
185
## Q & A
Libin Lu's avatar
Libin Lu committed
186
#### My android build is failing
Libin Lu's avatar
Libin Lu committed
187
Try update your SDK and google play service
188
#### I can't get notification when app is killed
Libin Lu's avatar
Libin Lu committed
189
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
Libin Lu's avatar
Libin Lu committed
190
#### App running in background doesn't trigger `FCMNotificationReceived` when receiving hybrid notification [Android]
191 192
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
193
Issues and pull requests are welcomed. Let's make this thing better!
Libin Lu's avatar
init  
Libin Lu committed
194