├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── RNPushNotificationAndroid ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── react-native-notifications.iml ├── react-native-push-notification.iml └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── dieam │ └── reactnativepushnotification │ ├── ReactNativePushNotificationPackage.java │ └── modules │ ├── RNPushNotification.java │ ├── RNPushNotificationHelper.java │ ├── RNPushNotificationListenerService.java │ └── RNPushNotificationRegistrationService.java ├── component ├── index.android.js └── index.ios.js ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IJ 26 | # 27 | .idea 28 | .gradle 29 | local.properties 30 | 31 | # node.js 32 | # 33 | node_modules/* 34 | npm-debug.log 35 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | npm-debug.log 29 | 30 | # OSX 31 | # 32 | .DS_Store 33 | 34 | # Xcode 35 | # 36 | build/ 37 | *.pbxuser 38 | !default.pbxuser 39 | *.mode1v3 40 | !default.mode1v3 41 | *.mode2v3 42 | !default.mode2v3 43 | *.perspectivev3 44 | !default.perspectivev3 45 | xcuserdata 46 | *.xccheckout 47 | *.moved-aside 48 | DerivedData 49 | *.hmap 50 | *.ipa 51 | *.xcuserstate 52 | project.xcworkspace 53 | 54 | # Android/IJ 55 | # 56 | react-native-notifications.iml 57 | .idea 58 | .gradle 59 | local.properties 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Dieam 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Native Push Notifications [![npm version](https://badge.fury.io/js/react-native-push-notification.svg)](http://badge.fury.io/js/react-native-push-notification) 2 | 3 | React Native Local and Remote Notifications for iOS and Android 4 | 5 | ## Installation 6 | `npm install react-native-push-notification` 7 | 8 | ## iOS Installation 9 | The component uses PushNotificationIOS for the iOS part. 10 | 11 | [Please see: PushNotificationIOS](https://facebook.github.io/react-native/docs/pushnotificationios.html#content) 12 | 13 | ## Android Installation 14 | In your `AndroidManifest.xml` 15 | ```xml 16 | ..... 17 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | ..... 46 | 47 | ``` 48 | 49 | In `android/settings.gradle` 50 | ```gradle 51 | ... 52 | 53 | include ':react-native-push-notification' 54 | project(':react-native-push-notification').projectDir = file('../node_modules/react-native-push-notification/RNPushNotificationAndroid') 55 | ``` 56 | 57 | In `android/app/build.gradle` 58 | 59 | ```gradle 60 | ... 61 | 62 | dependencies { 63 | ... 64 | 65 | compile project(':react-native-push-notification') 66 | } 67 | ``` 68 | 69 | Register module (in `MainActivity.java`) 70 | 71 | ```java 72 | import android.content.Intent; // <--- Import Intent 73 | import com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage; // <--- Import Package 74 | 75 | public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler { 76 | 77 | private ReactNativePushNotificationPackage mReactNativePushNotificationPackage; // <------ Add Package Variable 78 | 79 | /** 80 | * Returns the name of the main component registered from JavaScript. 81 | * This is used to schedule rendering of the component. 82 | */ 83 | @Override 84 | protected String getMainComponentName() { 85 | return "YOUR_APP_NAME"; 86 | } 87 | 88 | /** 89 | * Returns whether dev mode should be enabled. 90 | * This enables e.g. the dev menu. 91 | */ 92 | @Override 93 | protected boolean getUseDeveloperSupport() { 94 | return BuildConfig.DEBUG; 95 | } 96 | 97 | /** 98 | * A list of packages used by the app. If the app uses additional views 99 | * or modules besides the default ones, add more packages here. 100 | */ 101 | @Override 102 | protected List getPackages() { 103 | mReactNativePushNotificationPackage = new ReactNativePushNotificationPackage(this); // <------ Initialize the Package 104 | return Arrays.asList( 105 | new MainReactPackage(), 106 | new VectorIconsPackage(), 107 | new FabricPackage(), 108 | mReactNativePushNotificationPackage // <---- Add the Package 109 | ); 110 | } 111 | 112 | // Add onNewIntent 113 | @Override 114 | protected void onNewIntent (Intent intent) { 115 | super.onNewIntent(intent); 116 | 117 | mReactNativePushNotificationPackage.newIntent(intent); 118 | } 119 | 120 | .... 121 | } 122 | ``` 123 | 124 | ## Usage 125 | ```javascript 126 | var PushNotification = require('react-native-push-notification'); 127 | 128 | PushNotification.configure({ 129 | 130 | // (optional) Called when Token is generated (iOS and Android) 131 | onRegister: function(token) { 132 | console.log( 'TOKEN:', token ); 133 | }, 134 | 135 | // (required) Called when a remote or local notification is opened or received 136 | onNotification: function(notification) { 137 | console.log( 'NOTIFICATION:', notification ); 138 | }, 139 | 140 | // ANDROID ONLY: (optional) GCM Sender ID. 141 | senderID: "YOUR GCM SENDER ID", 142 | 143 | // IOS ONLY (optional): default: all - Permissions to register. 144 | permissions: { 145 | alert: true, 146 | badge: true, 147 | sound: true 148 | }, 149 | 150 | // Should the initial notification be popped automatically 151 | // default: true 152 | popInitialNotification: true, 153 | 154 | /** 155 | * IOS ONLY: (optional) default: true 156 | * - Specified if permissions will requested or not, 157 | * - if not, you must call PushNotificationsHandler.requestPermissions() later 158 | */ 159 | requestPermissions: true, 160 | }); 161 | ``` 162 | 163 | ## Handling Notifications 164 | When any notification is opened or received the callback `onNotification` is called passing an object with the notification data. 165 | 166 | Notification object example: 167 | ```javascript 168 | { 169 | foreground: false, // BOOLEAN: If the notification was received in foreground or not 170 | message: 'My Notification Message', // STRING: The notification message 171 | data: {}, // OBJECT: The push data 172 | } 173 | ``` 174 | 175 | ## Local and Schedule Notifications 176 | `PushNotification.localNotification(details: Object)` 177 | 178 | `PushNotification.localNotificationSchedule(details: Object)` (IOS ONLY) 179 | 180 | EXAMPLE: 181 | ```javascript 182 | PushNotification.localNotification({ 183 | /* Android Only Properties */ 184 | id: 0, // (optional) default: Autogenerated Unique ID 185 | title: "My Notification Title", // (optional) 186 | ticker: "My Notification Ticker", // (optional) 187 | largeIcon: "ic_launcher", // (optional) default: "ic_launcher" 188 | smallIcon: "ic_notification", // (optional) default: "ic_notification" with fallback for "ic_launcher" 189 | 190 | /* iOS and Android properties */ 191 | message: "My Notification Message" // (required) 192 | }); 193 | 194 | // IOS ONLY 195 | PushNotification.localNotificationSchedule({ 196 | message: "My Notification Message", // (required) 197 | date: new Date() 198 | }); 199 | ``` 200 | 201 | ## Sending Notification Data From Server 202 | Same parameters as `PushNotification.localNotification()` 203 | 204 | ## iOS Only Methods 205 | `PushNotification.checkPermissions(callback: Function)` Check permissions 206 | 207 | `PushNotification.setApplicationIconBadgeNumber(number: number)` set badge number 208 | 209 | `PushNotification.getApplicationIconBadgeNumber(callback: Function)` get badge number 210 | 211 | `PushNotification.abandonPermissions()` Abandon permissions 212 | 213 | ### TODO 214 | - [ ] Add `PushNotification.localNotificationSchedule()` Android support 215 | 216 | -------------------------------------------------------------------------------- /RNPushNotificationAndroid/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /RNPushNotificationAndroid/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | minSdkVersion 16 9 | targetSdkVersion 23 10 | versionCode 1 11 | versionName "1.0" 12 | ndk { 13 | abiFilters "armeabi-v7a", "x86" 14 | } 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | compile fileTree(dir: 'libs', include: ['*.jar']) 26 | testCompile 'junit:junit:4.12' 27 | compile 'com.android.support:appcompat-v7:23.1.1' 28 | compile 'com.facebook.react:react-native:0.16.+' 29 | compile 'com.google.android.gms:play-services-gcm:8.4.0' 30 | } 31 | -------------------------------------------------------------------------------- /RNPushNotificationAndroid/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.4.1/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /RNPushNotificationAndroid/react-native-notifications.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 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 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /RNPushNotificationAndroid/react-native-push-notification.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 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 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /RNPushNotificationAndroid/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /RNPushNotificationAndroid/src/main/java/com/dieam/reactnativepushnotification/ReactNativePushNotificationPackage.java: -------------------------------------------------------------------------------- 1 | package com.dieam.reactnativepushnotification; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | 6 | import com.dieam.reactnativepushnotification.modules.RNPushNotification; 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.bridge.JavaScriptModule; 9 | import com.facebook.react.bridge.NativeModule; 10 | import com.facebook.react.bridge.ReactApplicationContext; 11 | import com.facebook.react.uimanager.ViewManager; 12 | 13 | import java.util.ArrayList; 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | public class ReactNativePushNotificationPackage implements ReactPackage { 18 | Activity mActivity; 19 | RNPushNotification mRNPushNotification; 20 | 21 | public ReactNativePushNotificationPackage(Activity activity) { 22 | mActivity = activity; 23 | } 24 | 25 | @Override 26 | public List createNativeModules( 27 | ReactApplicationContext reactContext) { 28 | List modules = new ArrayList<>(); 29 | 30 | mRNPushNotification = new RNPushNotification(reactContext, mActivity); 31 | 32 | modules.add(mRNPushNotification); 33 | return modules; 34 | } 35 | 36 | @Override 37 | public List> createJSModules() { 38 | return Arrays.asList(); 39 | } 40 | 41 | @Override 42 | public List createViewManagers(ReactApplicationContext reactContext) { 43 | return new ArrayList<>(); 44 | } 45 | 46 | public void newIntent(Intent intent) { 47 | if(mRNPushNotification == null){ return; } 48 | mRNPushNotification.newIntent(intent); 49 | } 50 | } 51 | 52 | 53 | -------------------------------------------------------------------------------- /RNPushNotificationAndroid/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotification.java: -------------------------------------------------------------------------------- 1 | package com.dieam.reactnativepushnotification.modules; 2 | 3 | import android.app.Activity; 4 | import android.content.BroadcastReceiver; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | import android.os.Build; 8 | import android.os.Bundle; 9 | 10 | import com.facebook.react.bridge.Arguments; 11 | import com.facebook.react.bridge.ReactApplicationContext; 12 | import com.facebook.react.bridge.ReactContext; 13 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 14 | import com.facebook.react.bridge.ReactMethod; 15 | import com.facebook.react.bridge.ReadableMap; 16 | import com.facebook.react.bridge.WritableMap; 17 | import com.facebook.react.modules.core.DeviceEventManagerModule; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | import java.util.Set; 22 | import org.json.*; 23 | 24 | import android.content.Context; 25 | 26 | public class RNPushNotification extends ReactContextBaseJavaModule { 27 | private ReactContext mReactContext; 28 | private Activity mActivity; 29 | private RNPushNotificationHelper mRNPushNotificationHelper; 30 | 31 | public RNPushNotification(ReactApplicationContext reactContext, Activity activity) { 32 | super(reactContext); 33 | 34 | mActivity = activity; 35 | mReactContext = reactContext; 36 | mRNPushNotificationHelper = new RNPushNotificationHelper(activity.getApplication(), reactContext); 37 | registerNotificationsRegistration(); 38 | registerNotificationsReceiveNotification(); 39 | } 40 | 41 | @Override 42 | public String getName() { 43 | return "RNPushNotification"; 44 | } 45 | 46 | @Override 47 | public Map getConstants() { 48 | final Map constants = new HashMap<>(); 49 | 50 | Intent intent = mActivity.getIntent(); 51 | 52 | Bundle bundle = intent.getBundleExtra("notification"); 53 | if ( bundle != null ) { 54 | bundle.putBoolean("foreground", false); 55 | String bundleString = convertJSON(bundle); 56 | constants.put("initialNotification", bundleString); 57 | } 58 | 59 | return constants; 60 | } 61 | 62 | private void sendEvent(String eventName, Object params) { 63 | mReactContext 64 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 65 | .emit(eventName, params); 66 | } 67 | 68 | public void newIntent(Intent intent) { 69 | if ( intent.hasExtra("notification") ) { 70 | Bundle bundle = intent.getBundleExtra("notification"); 71 | bundle.putBoolean("foreground", false); 72 | intent.putExtra("notification", bundle); 73 | notifyNotification(bundle); 74 | } 75 | } 76 | 77 | private void registerNotificationsRegistration() { 78 | IntentFilter intentFilter = new IntentFilter("RNPushNotificationRegisteredToken"); 79 | 80 | mReactContext.registerReceiver(new BroadcastReceiver() { 81 | @Override 82 | public void onReceive(Context context, Intent intent) { 83 | String token = intent.getStringExtra("token"); 84 | WritableMap params = Arguments.createMap(); 85 | params.putString("deviceToken", token); 86 | 87 | sendEvent("remoteNotificationsRegistered", params); 88 | } 89 | }, intentFilter); 90 | } 91 | 92 | private void registerNotificationsReceiveNotification() { 93 | IntentFilter intentFilter = new IntentFilter("RNPushNotificationReceiveNotification"); 94 | 95 | mReactContext.registerReceiver(new BroadcastReceiver() { 96 | @Override 97 | public void onReceive(Context context, Intent intent) { 98 | notifyNotification(intent.getBundleExtra("notification")); 99 | } 100 | }, intentFilter); 101 | } 102 | 103 | private void notifyNotification(Bundle bundle) { 104 | String bundleString = convertJSON(bundle); 105 | 106 | WritableMap params = Arguments.createMap(); 107 | params.putString("dataJSON", bundleString); 108 | 109 | sendEvent("remoteNotificationReceived", params); 110 | } 111 | 112 | private String convertJSON(Bundle bundle) { 113 | JSONObject json = new JSONObject(); 114 | Set keys = bundle.keySet(); 115 | for (String key : keys) { 116 | try { 117 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 118 | json.put(key, JSONObject.wrap(bundle.get(key))); 119 | } else { 120 | json.put(key, bundle.get(key)); 121 | } 122 | } catch(JSONException e) { 123 | return null; 124 | } 125 | } 126 | return json.toString(); 127 | } 128 | 129 | @ReactMethod 130 | public void requestPermissions(String senderID) { 131 | Intent GCMService = new Intent(mReactContext, RNPushNotificationRegistrationService.class); 132 | 133 | GCMService.putExtra("senderID", senderID); 134 | mReactContext.startService(GCMService); 135 | } 136 | 137 | @ReactMethod 138 | public void cancelAllLocalNotifications() { 139 | mRNPushNotificationHelper.cancelAll(); 140 | } 141 | 142 | @ReactMethod 143 | public void presentLocalNotification(ReadableMap details) { 144 | Bundle bundle = Arguments.toBundle(details); 145 | mRNPushNotificationHelper.sendNotification(bundle); 146 | } 147 | 148 | @ReactMethod 149 | public void scheduleLocalNotification(ReadableMap details) { 150 | // TODO: Implement 151 | } 152 | 153 | } -------------------------------------------------------------------------------- /RNPushNotificationAndroid/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java: -------------------------------------------------------------------------------- 1 | package com.dieam.reactnativepushnotification.modules; 2 | 3 | 4 | import android.app.Application; 5 | import android.app.Notification; 6 | import android.app.NotificationManager; 7 | import android.app.PendingIntent; 8 | import android.content.Context; 9 | import android.content.Intent; 10 | import android.content.res.Resources; 11 | import android.graphics.Bitmap; 12 | import android.graphics.BitmapFactory; 13 | import android.media.RingtoneManager; 14 | import android.net.Uri; 15 | import android.os.Bundle; 16 | import android.support.v4.app.NotificationCompat; 17 | 18 | public class RNPushNotificationHelper { 19 | private Application mApplication; 20 | private Context mContext; 21 | 22 | public RNPushNotificationHelper(Application application, Context context) { 23 | mApplication = application; 24 | mContext = context; 25 | } 26 | 27 | public Class getMainActivityClass() { 28 | String packageName = mContext.getPackageName(); 29 | Intent launchIntent = mContext.getPackageManager().getLaunchIntentForPackage(packageName); 30 | String className = launchIntent.getComponent().getClassName(); 31 | try { 32 | return Class.forName(className); 33 | } catch (ClassNotFoundException e) { 34 | e.printStackTrace(); 35 | return null; 36 | } 37 | } 38 | 39 | public void sendNotification(Bundle bundle) { 40 | Class intentClass = getMainActivityClass(); 41 | if (intentClass == null) { 42 | return; 43 | } 44 | 45 | Resources res = mApplication.getResources(); 46 | String packageName = mApplication.getPackageName(); 47 | 48 | NotificationCompat.Builder notification = new NotificationCompat.Builder(mContext) 49 | .setContentTitle(bundle.getString("title")) 50 | .setTicker(bundle.getString("ticker")) 51 | .setCategory(NotificationCompat.CATEGORY_CALL) 52 | .setVisibility(NotificationCompat.VISIBILITY_PRIVATE) 53 | .setPriority(NotificationCompat.PRIORITY_HIGH) 54 | .setAutoCancel(true); 55 | 56 | if (bundle.getString("message") != null) { 57 | notification.setContentText(bundle.getString("message")); 58 | } else { 59 | this.cancelAll(); 60 | return; 61 | } 62 | 63 | String largeIcon = bundle.getString("largeIcon"); 64 | 65 | int smallIconResId; 66 | int largeIconResId; 67 | 68 | String smallIcon = bundle.getString("smallIcon"); 69 | 70 | if ( smallIcon != null ) { 71 | smallIconResId = res.getIdentifier(smallIcon, "mipmap", packageName); 72 | } else { 73 | smallIconResId = res.getIdentifier("ic_notification", "mipmap", packageName); 74 | } 75 | 76 | if ( smallIconResId == 0 ) { 77 | smallIconResId = res.getIdentifier("ic_launcher", "mipmap", packageName); 78 | 79 | if ( smallIconResId == 0 ) { 80 | smallIconResId = android.R.drawable.ic_dialog_info; 81 | } 82 | } 83 | 84 | if ( largeIcon != null ) { 85 | largeIconResId = res.getIdentifier(largeIcon, "mipmap", packageName); 86 | } else { 87 | largeIconResId = res.getIdentifier("ic_launcher", "mipmap", packageName); 88 | } 89 | 90 | Bitmap largeIconBitmap = BitmapFactory.decodeResource(res, largeIconResId); 91 | 92 | if ( largeIconResId != 0 && ( largeIcon != null || android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP ) ) { 93 | notification.setLargeIcon(largeIconBitmap); 94 | } 95 | 96 | notification.setSmallIcon(smallIconResId); 97 | 98 | int notificationID; 99 | String notificationIDString = bundle.getString("id"); 100 | 101 | if ( notificationIDString != null ) { 102 | notificationID = Integer.parseInt(notificationIDString); 103 | } else { 104 | notificationID = (int) System.currentTimeMillis(); 105 | } 106 | 107 | Intent intent = new Intent(mContext, intentClass); 108 | intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 109 | intent.putExtra("notification", bundle); 110 | 111 | PendingIntent pendingIntent = PendingIntent.getActivity(mContext, notificationID, intent, 112 | PendingIntent.FLAG_UPDATE_CURRENT); 113 | 114 | Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 115 | 116 | notification.setSound(defaultSoundUri); 117 | 118 | NotificationManager notificationManager = 119 | (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 120 | 121 | notification.setContentIntent(pendingIntent); 122 | 123 | Notification info = notification.build(); 124 | info.defaults |= Notification.DEFAULT_VIBRATE; 125 | info.defaults |= Notification.DEFAULT_SOUND; 126 | info.defaults |= Notification.DEFAULT_LIGHTS; 127 | 128 | notificationManager.notify(notificationID, info); 129 | } 130 | 131 | public void cancelAll() { 132 | NotificationManager notificationManager = 133 | (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 134 | 135 | notificationManager.cancelAll(); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /RNPushNotificationAndroid/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationListenerService.java: -------------------------------------------------------------------------------- 1 | package com.dieam.reactnativepushnotification.modules; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.app.ActivityManager; 6 | import android.app.ActivityManager.RunningAppProcessInfo; 7 | 8 | import java.util.List; 9 | 10 | import com.google.android.gms.gcm.GcmListenerService; 11 | 12 | public class RNPushNotificationListenerService extends GcmListenerService { 13 | 14 | @Override 15 | public void onMessageReceived(String from, Bundle bundle) { 16 | sendNotification(bundle); 17 | } 18 | 19 | private void sendNotification(Bundle bundle) { 20 | 21 | Boolean isRunning = isApplicationRunning(); 22 | 23 | Intent intent = new Intent("RNPushNotificationReceiveNotification"); 24 | bundle.putBoolean("foreground", isRunning); 25 | intent.putExtra("notification", bundle); 26 | sendBroadcast(intent); 27 | 28 | if (!isRunning) { 29 | new RNPushNotificationHelper(getApplication(), this).sendNotification(bundle); 30 | } 31 | } 32 | 33 | private boolean isApplicationRunning() { 34 | ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); 35 | List processInfos = activityManager.getRunningAppProcesses(); 36 | for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) { 37 | if (processInfo.processName.equals(getApplication().getPackageName())) { 38 | if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { 39 | for (String d: processInfo.pkgList) { 40 | return true; 41 | } 42 | } 43 | } 44 | } 45 | return false; 46 | } 47 | } -------------------------------------------------------------------------------- /RNPushNotificationAndroid/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationRegistrationService.java: -------------------------------------------------------------------------------- 1 | package com.dieam.reactnativepushnotification.modules; 2 | 3 | import android.app.IntentService; 4 | import android.content.Intent; 5 | 6 | import com.google.android.gms.gcm.GoogleCloudMessaging; 7 | import com.google.android.gms.iid.InstanceID; 8 | 9 | public class RNPushNotificationRegistrationService extends IntentService { 10 | 11 | private static final String TAG = "RNPushNotification"; 12 | 13 | public RNPushNotificationRegistrationService() {super(TAG);} 14 | 15 | @Override 16 | protected void onHandleIntent(Intent intent) { 17 | String SenderID = intent.getStringExtra("senderID"); 18 | 19 | try { 20 | InstanceID instanceID = InstanceID.getInstance(this); 21 | String token = instanceID.getToken(SenderID, 22 | GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); 23 | sendRegistrationToken(token); 24 | } catch (Exception e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | 29 | private void sendRegistrationToken(String token) { 30 | Intent intent = new Intent("RNPushNotificationRegisteredToken"); 31 | intent.putExtra("token", token); 32 | sendBroadcast(intent); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /component/index.android.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var { 4 | NativeModules, 5 | DeviceEventEmitter, 6 | } = require('react-native'); 7 | 8 | var RNPushNotification = NativeModules.RNPushNotification; 9 | var _notifHandlers = new Map(); 10 | 11 | var DEVICE_NOTIF_EVENT = 'remoteNotificationReceived'; 12 | var NOTIF_REGISTER_EVENT = 'remoteNotificationsRegistered'; 13 | 14 | var NotificationsComponent = function() { 15 | this.initalPop = false; 16 | }; 17 | 18 | NotificationsComponent.prototype.popInitialNotification = function() { 19 | if ( this.initalPop === false && 20 | RNPushNotification.initialNotification ) { 21 | this.initalPop = true; 22 | return JSON.parse(RNPushNotification.initialNotification); 23 | } else { 24 | return null; 25 | } 26 | }; 27 | 28 | NotificationsComponent.prototype.requestPermissions = function(senderID: string) { 29 | RNPushNotification.requestPermissions(senderID); 30 | }; 31 | 32 | NotificationsComponent.prototype.cancelAllLocalNotifications = function() { 33 | RNPushNotification.cancelAllLocalNotifications(); 34 | }; 35 | 36 | NotificationsComponent.prototype.presentLocalNotification = function(details: Object) { 37 | RNPushNotification.presentLocalNotification(details); 38 | }; 39 | 40 | NotificationsComponent.prototype.scheduleLocalNotification = function(details: Object) { 41 | RNPushNotification.scheduleLocalNotification(details); 42 | }; 43 | 44 | NotificationsComponent.prototype.abandonPermissions = function() { 45 | /* Void */ 46 | }; 47 | 48 | NotificationsComponent.prototype.checkPermissions = function(callback: Function) { 49 | /* Void */ 50 | }; 51 | 52 | NotificationsComponent.prototype.addEventListener = function(type: string, handler: Function) { 53 | var listener; 54 | if (type === 'notification') { 55 | listener = DeviceEventEmitter.addListener( 56 | DEVICE_NOTIF_EVENT, 57 | function(notifData) { 58 | var data = JSON.parse(notifData.dataJSON); 59 | handler(data); 60 | } 61 | ); 62 | } else if (type === 'register') { 63 | listener = DeviceEventEmitter.addListener( 64 | NOTIF_REGISTER_EVENT, 65 | function(registrationInfo) { 66 | handler(registrationInfo.deviceToken); 67 | } 68 | ); 69 | } 70 | 71 | _notifHandlers.set(handler, listener); 72 | }; 73 | 74 | NotificationsComponent.prototype.removeEventListener = function(type: string, handler: Function) { 75 | var listener = _notifHandlers.get(handler); 76 | if (!listener) { 77 | return; 78 | } 79 | listener.remove(); 80 | _notifHandlers.delete(handler); 81 | } 82 | 83 | module.exports = { 84 | state: false, 85 | component: new NotificationsComponent() 86 | }; 87 | 88 | -------------------------------------------------------------------------------- /component/index.ios.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | 4 | var React = require('react-native'); 5 | 6 | var { 7 | AppStateIOS, 8 | PushNotificationIOS 9 | } = React; 10 | 11 | module.exports = { 12 | state: AppStateIOS, 13 | component: PushNotificationIOS 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @providesModule Notifications 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var RNNotificationsComponent = require( './component' ); 8 | 9 | var AppState = RNNotificationsComponent.state; 10 | var RNNotifications = RNNotificationsComponent.component; 11 | 12 | var Platform = require('react-native').Platform; 13 | 14 | var Notifications = { 15 | handler: RNNotifications, 16 | onRegister: false, 17 | onError: false, 18 | onNotification: false, 19 | 20 | loaded: false, 21 | 22 | permissions: { 23 | alert: true, 24 | badge: true, 25 | sound: true 26 | } 27 | }; 28 | 29 | Notifications.callNative = function(name: String, params: Array) { 30 | if ( typeof this.handler[name] === 'function' ) { 31 | if ( typeof params !== 'array' && 32 | typeof params !== 'object' ) { 33 | params = []; 34 | } 35 | 36 | return this.handler[name](...params); 37 | } else { 38 | return null; 39 | } 40 | }; 41 | 42 | /** 43 | * Configure local and remote notifications 44 | * @param {Object} options 45 | * @param {function} options.onRegister - Fired when the user registers for remote notifications. 46 | * @param {function} options.onNotification - Fired when a remote notification is received. 47 | * @param {function} options.onError - None 48 | * @param {Object} options.permissions - Permissions list 49 | * @param {Boolean} options.requestPermissions - Check permissions when register 50 | */ 51 | Notifications.configure = function(options: Object) { 52 | if ( typeof options.onRegister !== 'undefined' ) { 53 | this.onRegister = options.onRegister; 54 | } 55 | 56 | if ( typeof options.onError !== 'undefined' ) { 57 | this.onError = options.onError; 58 | } 59 | 60 | if ( typeof options.onNotification !== 'undefined' ) { 61 | this.onNotification = options.onNotification; 62 | } 63 | 64 | if ( typeof options.permissions !== 'undefined' ) { 65 | this.permissions = options.permissions; 66 | } 67 | 68 | if ( typeof options.senderID !== 'undefined' ) { 69 | this.senderID = options.senderID; 70 | } 71 | 72 | if ( this.loaded === false ) { 73 | this.callNative( 'addEventListener', [ 'register', this._onRegister.bind(this) ] ) 74 | this.callNative( 'addEventListener', [ 'notification', this._onNotification.bind(this) ] ) 75 | 76 | if ( typeof options.popInitialNotification === 'undefined' || options.popInitialNotification === true ) { 77 | var tempFirstNotification = this.callNative( 'popInitialNotification' ); 78 | 79 | if ( tempFirstNotification !== null ) { 80 | this._onNotification(tempFirstNotification, true); 81 | } 82 | } 83 | 84 | this.loaded = true; 85 | } 86 | 87 | if ( options.requestPermissions !== false ) { 88 | this.requestPermissions(); 89 | } 90 | 91 | }; 92 | 93 | /* Unregister */ 94 | Notifications.unregister = function() { 95 | this.callNative( 'removeEventListener', [ 'register', this._onRegister.bind(this) ] ) 96 | this.callNative( 'removeEventListener', [ 'notification', this._onNotification.bind(this) ] ) 97 | }; 98 | 99 | /** 100 | * Local Notifications 101 | * @param {Object} details 102 | * @param {String} details.message - The message displayed in the notification alert. 103 | * @param {String} details.title - ANDROID ONLY: The title displayed in the notification alert. 104 | * @param {String} details.ticker - ANDROID ONLY: The ticker displayed in the status bar. 105 | */ 106 | Notifications.localNotification = function(details: Object) { 107 | if ( Platform.OS === 'ios' ) { 108 | this.handler.presentLocalNotification({ 109 | alertBody: details.message 110 | }); 111 | } else { 112 | this.handler.presentLocalNotification(details); 113 | } 114 | }; 115 | 116 | /** 117 | * Local Notifications Schedule 118 | * @param {Object} details (same as localNotification) 119 | * @param {Date} details.date - The date and time when the system should deliver the notification 120 | */ 121 | Notifications.localNotificationSchedule = function(details: Object) { 122 | if ( Platform.OS === 'ios' ) { 123 | this.handler.scheduleLocalNotification({ 124 | fireDate: details.date, 125 | alertBody: details.message 126 | }); 127 | } else { 128 | this.handler.scheduleLocalNotification(details); 129 | } 130 | }; 131 | 132 | /* Internal Functions */ 133 | Notifications._onRegister = function(token: String) { 134 | if ( this.onRegister !== false ) { 135 | this.onRegister({ 136 | token: token, 137 | os: Platform.OS 138 | }); 139 | } 140 | }; 141 | 142 | Notifications._onNotification = function(data, isFromBackground = null) { 143 | if ( isFromBackground === null ) { 144 | if ( Platform.OS === 'ios' ) { 145 | isFromBackground = ( AppState.currentState === 'background' ); 146 | } else { 147 | isFromBackground = ( data.foreground === false ); 148 | } 149 | } 150 | 151 | if ( this.onNotification !== false ) { 152 | if ( Platform.OS === 'ios' ) { 153 | this.onNotification({ 154 | foreground: ! isFromBackground, 155 | message: data.getMessage(), 156 | data: data.getData(), 157 | }); 158 | } else { 159 | this.onNotification({ 160 | foreground: ! isFromBackground, 161 | message: data.message, 162 | data: ( 163 | typeof data.data !== 'undefined' 164 | ? data.data 165 | : {} 166 | ), 167 | }); 168 | } 169 | } 170 | }; 171 | 172 | Notifications.requestPermissions = function() { 173 | if ( Platform.OS === 'ios' ) { 174 | return this.callNative( 'requestPermissions', [ this.permissions ]); 175 | } else if ( typeof this.senderID !== 'undefined' ) { 176 | return this.callNative( 'requestPermissions', [ this.senderID ]); 177 | } 178 | }; 179 | 180 | /* Fallback functions */ 181 | Notifications.presentLocalNotification = function() { 182 | return this.callNative('presentLocalNotification', arguments); 183 | }; 184 | 185 | Notifications.scheduleLocalNotification = function() { 186 | return this.callNative('scheduleLocalNotification', arguments); 187 | }; 188 | 189 | Notifications.cancelAllLocalNotifications = function() { 190 | return this.callNative('cancelAllLocalNotifications', arguments); 191 | }; 192 | 193 | Notifications.cancelAllLocalNotifications = function() { 194 | return this.callNative('cancelAllLocalNotifications', arguments); 195 | }; 196 | 197 | Notifications.setApplicationIconBadgeNumber = function() { 198 | return this.callNative('setApplicationIconBadgeNumber', arguments); 199 | }; 200 | 201 | Notifications.getApplicationIconBadgeNumber = function() { 202 | return this.callNative('getApplicationIconBadgeNumber', arguments); 203 | }; 204 | 205 | Notifications.popInitialNotification = function() { 206 | return this.callNative('popInitialNotification', arguments); 207 | }; 208 | 209 | Notifications.abandonPermissions = function() { 210 | return this.callNative('abandonPermissions', arguments); 211 | }; 212 | 213 | Notifications.checkPermissions = function() { 214 | return this.callNative('checkPermissions', arguments); 215 | }; 216 | 217 | module.exports = Notifications; 218 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-push-notification", 3 | "version": "1.0.3", 4 | "description": "React Native Local and Remote Notifications", 5 | "main": "index", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "react-component", 11 | "react-native", 12 | "ios", 13 | "android", 14 | "notifications", 15 | "push", 16 | "apns", 17 | "gcm" 18 | ], 19 | "bugs": { 20 | "url": "https://github.com/zo0r/react-native-push-notification/issues" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "git+ssh://git@github.com:zo0r/react-native-push-notification.git" 25 | }, 26 | "peerDependencies": { 27 | "react-native": ">=0.16" 28 | }, 29 | "author": "zo0r ", 30 | "license": "MIT" 31 | } 32 | --------------------------------------------------------------------------------