Introduction
My requirements were simple I needed to incorporate Local notifications that I could schedule to to appear at a later time for both iOS and Android. I also needed these notifications to still display even if the app was closed. After some research I found that react-native-push-notification was my best bet. However, I found that this was a bit tricky to get up and running, but at long last I was successful. My struggle is your lucky day.
Full App Repo: https://github.com/edmondso006/ReactNativeLocalNotifications
Installation
We are actually going to have to install two packages because the react-native-push-notification
package utilizes push-notifications-ios
in order to send iOS notifications. These packages also support Push Notifications but that is out of scope of this tutorial.
npm install --save react-native-push-notification
npm install --save @react-native-community/push-notification-ios
Since we are going to be using native features on the device we need to Manually Link these packages. To do that run the following commands. Linking allows you to use the native features of the device!
react-native link react-native-push-notification
react-native link @react-native-community/push-notification-ios
## iOS Setup
Since we install a native module it is a good idea to run pod install
in the iOS directory. This will give you access to the module we install through npm in xCode
cd ios
pod install
Since we want to use both local and scheduled notifications we need to add some Objective-C code in the AppDelegate.m
file of the application. For this you are going to want to navigate to the iOS directory in your app folder and open the .xcworkspace
file. ( Notifications/ios/Notifications.xcworkspace
). Then open the AppDelegate.m
.
First import the module that we installed through npm.
#import <RNCPushNotificationIOS.h>
Then add the following code into the body.
// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
[RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[RNCPushNotificationIOS didReceiveLocalNotification:notification];
}
Now is a good time to try and build the project in xCode. If you did everything correctly you should have a successful build. If not make sure that you ran pod install
in the iOS directory of your application. Thats it for the iOS Setup!
Android Setup
Since we are going to want to use local scheduled notifications we are going to need to add some code to the android/app/src/main/AndroidManifest.xml
file. Outside of the <application>
tag but within the <manifest>
tag add the following code:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Then add the following code within the <application>
tag:
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name"
android:value="YOUR NOTIFICATION CHANNEL NAME"/>
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_de scription"
android:value="YOUR NOTIFICATION CHANNEL DESCRIPTION"/>
<!-- Change the resource name to your App's accent color - or any other color you want -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
android:resource="@android:color/white"/>
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
<receiver android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationRegistrationService"/>
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
<service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerServiceGcm"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<!-- </ Only if you're using GCM or localNotificationSchedule() > -->
<service
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
And finally, create the file android/app/src/res/values/colors.xml
and add the following:
<resources>
<color name="white">#FFF</color>
</resources>
That's it for the Android Setup!
Putting it all together!
In order to keep things simple and clean let's create a file call NotificationService.js
. This file is where all of our Notification code will go. Add the following to that file:
import PushNotification from 'react-native-push-notification';
export default class NotificationService {
//onNotificaitn is a function passed in that is to be called when a
//notification is to be emitted.
constructor(onNotification) {
this.configure(onNotification);
this.lastId = 0;
}
configure(onNotification) {
PushNotification.configure({
onNotification: onNotification,
// IOS ONLY (optional): default: all - Permissions to register.
permissions: {
alert: true,
badge: true,
sound: true
},
popInitialNotification: true,
});
}
//Appears right away
localNotification() {
this.lastId++;
PushNotification.localNotification({
title: "Local Notification",
message: "My Notification Message",
playSound: false,
soundName: 'default',
actions: '["Yes", "No"]'
});
}
//Appears after a specified time. App does not have to be open.
scheduleNotification() {
this.lastId++;
PushNotification.localNotificationSchedule({
date: new Date(Date.now() + (30 * 1000)), //30 seconds
title: "Scheduled Notification",
message: "My Notification Message",
playSound: true,
soundName: 'default',
});
}
checkPermission(cbk) {
return PushNotification.checkPermissions(cbk);
}
cancelNotif() {
PushNotification.cancelLocalNotifications({id: ''+this.lastId});
}
cancelAll() {
PushNotification.cancelAllLocalNotifications();
}
}
Note: This is the absolute basics. Consult the Github repos for more information
Add the following to your app.js
import React, { Component } from 'react';
import {
SafeAreaView,
StyleSheet,
ScrollView,
View,
Text,
StatusBar,
Button,
Alert
} from 'react-native';
import {
Header,
Colors,
} from 'react-native/Libraries/NewAppScreen';
import NotificationService from './NotificationService';
class App extends Component {
constructor(props) {
super(props);
//creating a new instance of the NotificationService
//& passing in the function we want called when the notification happens
this.notification = new NotificationService(this.onNotification);
}
//Gets called when the notification comes in
onNotification = (notif) => {
Alert.alert(notif.title, notif.message);
}
//Permissions to use notifications
handlePerm(perms) {
Alert.alert("Permissions", JSON.stringify(perms));
}
render(){
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={styles.scrollView}>
<Header />
{global.HermesInternal == null ? null : (
<View style={styles.engine}>
<Text style={styles.footer}>Engine: Hermes</Text>
</View>
)}
<View style={styles.body}>
<Button title={"Local Notification"} onPress={() => { this.notification.localNotification() }} />
<Button title={"Scheduled (30s) Notification"} onPress={() => { this.notification.scheduleNotification() }} />
</View>
</ScrollView>
</SafeAreaView>
</>
);
}
}
const styles = StyleSheet.create({
scrollView: {
backgroundColor: Colors.lighter,
},
engine: {
position: 'absolute',
right: 0,
},
body: {
backgroundColor: Colors.white,
},
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
color: Colors.black,
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
color: Colors.dark,
},
highlight: {
fontWeight: '700',
},
footer: {
color: Colors.dark,
fontSize: 12,
fontWeight: '600',
padding: 4,
paddingRight: 12,
textAlign: 'right',
},
});
export default App;
Wrap up
If everything was successful you should be able to schedule local notifications! Here the the repo for the project: https://github.com/edmondso006/ReactNativeLocalNotifications. If you have any questions please feel free to reach out and ask.
Sources
https://github.com/zo0r/react-native-push-notification
https://github.com/react-native-community/react-native-push-notification-ios
React Native Local iOS and Android Notifications
My requirements were simple I needed to incorporate Local notifications that I could schedule to to appear at a later time for both iOS and Android. I also needed these notifications to still display even if the app was closed.