How to use Push Notifications in React-Native (IOS)

What is React-Native

React Native enables you to build world-class application experiences on native platforms using a consistent developer experience based on JavaScript and React. The focus of React Native is on developer efficiency across all the platforms you care about — learn once, write anywhere. Facebook uses React Native in multiple production apps and will continue investing in React Native.
Source: https://facebook.github.io/react-native

Progress of push notifications in React-Native.

Push notifications are working in React-Native v0.13 and higher. However it is not fully implemented yet. At the moment there is no error handling and only static push notifications are supported. There is no support for interactive notifications in React-Native.

There are some Pull Requests and issues listed, so a it is still a work in progress.

React-Native v0.12 and lower.

There is a bug React-Native v0.12 and lower which will prevent push notifications in IOS 8 and higher. The Pull Request for this bug is merged in v0.13. For the people who want to use v0.12 and lower I have included a step by step guide on how to implement this Pull Request yourself. You can find this guide below in the section Bugfix.

Requirements:

In order to use push notifications you will need:

  • An Apple Developer license.
  • An physical IOS device. (Push notifications are not working in the simulator!)
  • A React-Native Project (The getting started guide)

Steps

To get push notifications working in React-Native you have to follow these steps.

  • Add Push Notifications Library to your project.
  • Add a Header Path
  • Modify AppDelegate.m
  • Bug Fix (only for v0.12 and lower)
  • Get your certificates.
  • Start using Push Notifications in React-Native.

Add the library

The first thing we have to do is to add the PushNotificationIOS library to our project. This step is very well documented by React-Native and it can be found on this page. You can choose to follow the original docs or just follow the steps below. (The steps are the same, but the ones below are a little more detailed).

  • Open your project in Xcode
  • Open the Library directory (in Xcode)
  • Open your project in a file window and go to node_modules/react-native/Libraries/PushNotificationIOS
  • Drag RCTPushNotification.xcodeproj into your Library directory in Xcode.
Source: https://facebook.github.io/react-native/docs/linking-libraries-ios.html#content

The library is now added to your project. The next thing we have to do is to link the binary.

  • Click once on your project (1) in Xcode and go to Build Phases (2)
Source: https://facebook.github.io/react-native/docs/linking-libraries-ios.html#content
  • Drag libRCTPushNotification.a to Link Binary With Libraries (3)

For most of the React-Native libraries, adding and linking the library is all it takes to get up and running. But if you want to use the PushNotification library we need to take a few more steps.

Add a Header Path

Now that the library is added to your project we will need to add a Header Path. The Header path we are going to add points to the location of the Libraries directory. By adding this Header Path we make sure that xCode can find our PushNotifications Library.

Note: Adding a Header Path is only required when a React-Native library is using native IOS code (PushNotifcationIOS, LinkingIOS or third-party libraries).

Follow these steps to add a Header Path to your project:

  • Click once on your project in Xcode (1)
  • Go to Build Settings (2)
  • Search for: “header search paths” (3)
  • Double click on the path besides the Header Search Paths
  • Add a new path (4)
  • Enter the path that belongs to your app: (5)

A normal React-Native app: $(SRCROOT)/node_modules/react-native/Libraries

The SampleApp: $(SRCROOT)/../../../Libraries

Any other example app: $(SRCROOT)/../../Libraries

  • Make sure that path is recursive (6)

The added Header Search Path will enable you to require the Library in AppDelegate.m

Modify AppDelegate.m

The PushNotificationIOS library is using a few Objective-C methods to register and to receive push notifications. However those methods can only be used in AppDelegate. Therefore we will need to add a few lines of code that will pass the data from the AppDelegate to our PushNotificationIOS library.

  • The first thing we need to do is to import RCTPushNotificationManager.h Add this line below the other imports in AppDelegate.m
#import "RCTPushNotificationManager.h"
  • The second thing we need to do is to add these lines to the bottom of AppDelegate.m

React-native v0.17 and lower:

// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[RCTPushNotificationManager application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification
{
[RCTPushNotificationManager application:application didReceiveRemoteNotification:notification];
}

React-native v0.18 and higher:

// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { [RCTPushNotificationManager didRegisterUserNotificationSettings:notificationSettings]; }
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [RCTPushNotificationManager didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; }
// Required for the notification event.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification
{
[RCTPushNotificationManager didReceiveRemoteNotification:notification];
}

These methods will pass the data from our AppDelegate to the PushNotificationIOS library. Without those lines the register and the notification events will not work in Javascript. Next up is the bug fix.

Bug fix

(Only for React-Native v0.12 and lower)

There is a bug in React-Native which will prevent push notifications from working in IOS 8 and higher in React-Native v0.12 and lower. The solution is very easy to fix yourself.

Steps to fix the bug:

  • In Xcode: go to the Libraries directory and open RCTPushNotification.xcodeproj/RCTPushNotificationManager.m
  • Scroll and find: (around line 155)
Pull Request: https://github.com/facebook/react-native/pull/2332/files

If you use React-Native v0.11 or lower use: (v0.12 is below)

  • replace it with: (you can copy the code below this image)
This is how the bug fix should look like.

Code you can copy and paste: (maybe you have to fix the indentation)

UIApplication *app = [UIApplication sharedApplication];
if ([app respondsToSelector:@selector(registerUserNotificationSettings:)]){
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:(NSUInteger)types categories:nil];
[app registerUserNotificationSettings:notificationSettings];
[app registerForRemoteNotifications];
} else {
[app registerForRemoteNotificationTypes:(NSUInteger)types];
}

If you use React-Native v0.12:

  • replace it with: (you can copy the code below this image)
This is how the bug fix should look like.

Code you can copy and paste: (maybe you have to fix the indentation)

UIApplication *app = RCTSharedApplication();
if ([app respondsToSelector:@selector(registerUserNotificationSettings:)]){
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:(NSUInteger)types categories:nil];
[app registerUserNotificationSettings:notificationSettings];
[app registerForRemoteNotifications];
} else {
[app registerForRemoteNotificationTypes:(NSUInteger)types];
}

  • Save the file and the bug is fixed!

Now that we have added those lines to our project we are done modifying the project in Xcode. The next thing we have to do is to get our certificates.

Get your certificates.

As you probably know push notifications are send from Apple servers to your application. And in order to get this working you will need to get a few valid certificates. There is already an excellent tutorial written about this subject by Parse. The tutorial is step by step and it is really easy to follow. Just follow step 1 (Creating the SSL certificate) and 2 (Creating the Provisioning Profile).

Tutorial: https://parse.com/tutorials/ios-push-notifications

Once you have finished this step you are ready to go and you can now start using push notifications in your React-Native project.

Start using Push Notifications in React-Native.

The Api for push notifications in React-Native is pretty straight forward. The official documentation can be found here and a summary can be found down below.

A quick summary:

Make PushNotificationIOS available in Javascript:

var {
AppRegistry,
StyleSheet,
Text,
View,
PushNotificationIOS // <- Add this line!
} = React;

Api: Request permission:

PushNotificationIOS.requestPermissions();

Api: Register event

Official docs: Fired when the user registers for remote notifications. The handler will be invoked with a hex string representing the deviceToken.

PushNotificationIOS.addEventListener(‘register’, function(token){
console.log(‘You are registered and the device token is: ‘,token)
});

Api: Notification event.

Official docs: Fired when a remote notification is received. The handler will be invoked with an instance of PushNotificationIOS.

PushNotificationIOS.addEventListener(‘notification’, function(notification){
console.log(‘You have received a new notification!’, notification);
});

Pull Request: Error event

At the moment it is impossible to see any errors that occur within PushNotificationIOS. Normally in IOS you will get an error when for example: certificates are not valid/available or when you run your app in a simulator but error handling is not implemented right now in PushNotificationIOS.

I have created a Pull Request which will add an error event to PushNotificationIOS. The error event will be invoked with the original IOS error message and the error key.

Pull Request: https://github.com/facebook/react-native/pull/2336

I will update this article when the PR is merged.

How to send a Push Notification?

In order to send push notifications you will need a backend and a few more certificates. You can use a service or you can create your own backend.

Service

There are some services that make sending push notifications very easy like Parse and Urban Airship.

Create your own backend

Certificates

You will need a few more certificates when you setup a backend for push notifications. There is a Stack overflow thread which explains the process for these certificates.


If you have any questions or comments:

Twitter: @DannyvanderJagt

Github: @DannyvanderJagt