React Native Local iOS and Android Notifications
Tags: react, javascript, tutorial, reactnative
Published: 2019-11-14 01:15:55

---
title: React Native Local iOS and Android Notifications
published: true
description: React Native Local Scheduleable Notifications
tags: react, javascript, tutorial, react-native
---

## 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](https://github.com/zo0r/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](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. 
```bash
    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! 
```bash
    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
```bash
    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.
```objective-c
    #import <RNCPushNotificationIOS.h>
```
Then add the following code into the body.
```objective-c
    // 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:
```xml
    <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:
```xml
    <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_description"
                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:
```javascript
    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`
```javascript
    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](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/zo0r/react-native-push-notification)

[https://github.com/react-native-community/react-native-push-notification-ios](https://github.com/react-native-community/react-native-push-notification-ios)