Commit a761a982 authored by Antoine Rousseau's avatar Antoine Rousseau

fix #48: Add ProGuard information & improve README

parent 7171e235
...@@ -3,126 +3,158 @@ ...@@ -3,126 +3,158 @@
## Installation ## Installation
- Run `npm install react-native-fcm --save` - Run `npm install react-native-fcm --save`
- Run `rnpm link` - Run `react-native link react-native-fcm` (RN 0.29.1+, otherwise `rnpm link react-native-fcm`)
Or you can combine 2 commands
- Run `rnpm install react-native-fcm`
## Android Configuration ## Android Configuration
- In `android/build.gradle` - Edit `android/build.gradle`:
```gradle ```diff
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.0.0' classpath 'com.android.tools.build:gradle:2.0.0'
classpath 'com.google.gms:google-services:3.0.0' // <- Add this line + classpath 'com.google.gms:google-services:3.0.0'
``` ```
- In `android/app/build.gradle` - Edit `android/app/build.gradle`:
```gradle ```diff
apply plugin: "com.android.application" apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services' // <- Add this line + apply plugin: 'com.google.gms.google-services'
...
``` ```
- In `android/app/src/main/AndroidManifest.xml` - Edit `android/app/src/main/AndroidManifest.xml`:
```diff
<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>
...
``` ```
<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>
...
```
### Config for notification and `click_action` in Android ### 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 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
Edit `AndroidManifest.xml`:
```diff
<activity
android:name=".MainActivity" android:name=".MainActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:windowSoftInputMode="adjustResize" android:windowSoftInputMode="adjustResize"
android:launchMode="singleTop" <--add this line to reuse MainActivity + android:launchMode="singleTop"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<intent-filter> <--add this line + <intent-filter>
<action android:name="fcm.ACTION.HELLO" /> <--add this line, name should match click_action + <action android:name="fcm.ACTION.HELLO" />
<category android:name="android.intent.category.DEFAULT" /> <--add this line + <category android:name="android.intent.category.DEFAULT" />
</intent-filter> <--add this line + </intent-filter>
</activity> </activity>
``` ```
and pass intent into package, change MainActivity.java
```java Notes:
import android.content.Intent; <--add this line next to the other imports - `launchMode="singleTop"` is to reuse MainActivity
- replace `"fcm.ACTION.HELLO"` by the `click_action` you want to match
// Add this line to update intent on notification click
@Override
// in RN <= 0.27 you may need to use `protected void onNewIntent (Intent intent) {` And pass intent into package, edit `MainActivity.java`:
public void onNewIntent (Intent intent) {
super.onNewIntent(intent); - RN 0.28+:
setIntent(intent);
} ```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 ## IOS Configuration
### Pod approach: ### Pod approach:
install pod 'Firebase/Messaging' Make sure you have Cocoapods version > 1.0
NOTE: make sure cocoapods version > 1.0
Install the `Firebase/Messaging` pod:
``` ```
cd ios && pod init cd ios && pod init
pod install Firebase/Messaging pod install Firebase/Messaging
``` ```
### Non Cocoapod approach ### Non Cocoapod approach
1. download framework from https://firebase.google.com/docs/ios/setup last section Integrate without CocoaPods
2. Follow the readme to link frameworks (Analytics+Messaging) 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 ### Shared steps
in AppDelegate.m add
```
#import "Firebase.h" <--add if you are using Non Cocoapod approach
#import "RNFIRMessaging.h" <--add this line
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
....
[FIRApp configure]; <-- add this line
}
//add this method Edit `AppDelegate.m`:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler { ```diff
[[NSNotificationCenter defaultCenter] postNotificationName:FCMNotificationReceived object:self userInfo:notification]; + #import "Firebase.h" // if you are using Non Cocoapod approach
handler(UIBackgroundFetchResultNewData); + #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 ### 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`) 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 ## Usage
```javascript ```javascript
import FCM from 'react-native-fcm'; import FCM from 'react-native-fcm';
... class App extends Component {
componentWillMount() { componentDidMount() {
FCM.requestPermissions(); FCM.requestPermissions(); // for iOS
FCM.getFCMToken().then(token => { FCM.getFCMToken().then(token => {
console.log(token) console.log(token)
// store fcm token in your server // store fcm token in your server
...@@ -140,11 +172,11 @@ In [firebase console](https://console.firebase.google.com/), you can get `google ...@@ -140,11 +172,11 @@ In [firebase console](https://console.firebase.google.com/), you can get `google
} }
componentWillUnmount() { componentWillUnmount() {
// prevent leak // prevent leaking
this.refreshUnsubscribe(); this.refreshUnsubscribe();
this.notificationUnsubscribe(); this.notificationUnsubscribe();
} }
... }
``` ```
### Behaviour when sending `notification` and `data` payload through GCM ### Behaviour when sending `notification` and `data` payload through GCM
...@@ -159,8 +191,9 @@ In [firebase console](https://console.firebase.google.com/), you can get `google ...@@ -159,8 +191,9 @@ In [firebase console](https://console.firebase.google.com/), you can get `google
* if you pass `notification` payload. it will receive data when user click on notification * 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 * if you pass `data` payload only, it will receive data when in background
e.g. fcm payload looks like e.g. fcm payload looks like:
```
```json
{ {
"to":"some_device_token", "to":"some_device_token",
"content_available": true, "content_available": true,
...@@ -174,34 +207,51 @@ In [firebase console](https://console.firebase.google.com/), you can get `google ...@@ -174,34 +207,51 @@ In [firebase console](https://console.firebase.google.com/), you can get `google
} }
} }
``` ```
and event callback will receive as
``` and event callback will receive as:
///Android
- Android
```json
{ {
fcm: {"action": "fcm.ACTION.HELLO"}, "fcm": {"action": "fcm.ACTION.HELLO"},
extra: "juice" "extra": "juice"
} }
///IOS ```
- iOS
```json
{ {
apns: {action_category: "fcm.ACTION.HELLO"}, "apns": {"action_category": "fcm.ACTION.HELLO"},
extra: "juice" "extra": "juice"
} }
``` ```
- When app is running in foreground - 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.) - 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) 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 ## Q & A
#### My android build is failing
#### My Android build is failing
Try update your SDK and google play service Try update your SDK and google play service
#### I can't get notification when app is killed #### 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 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] #### 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 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 #### Android notification is showing a white icon
Since Lolipop, push notification icon is required to be all white, otherwise it will be a white circle. Since Lollipop, the push notification icon is required to be all white, otherwise it will be a white circle.
#### It is missing some features
Issues and pull requests are welcomed. Let's make this thing better! #### 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!
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment