React Native Push Notifications with OneSignal
I had initially planned to make a comprehensive multi-part video series on setting up remote push notifications but, unfortunately, I underestimated the time it would take for me to recover from getting my wisdom teeth removed.
But that’s no excuse. Here’s a tutorial on how to set up push notifications in React Native (both iOS and Android) with OneSignal, a service that provides free push notification delivery for multiple platforms. This is a pretty long tutorial but it’s worth it. Even if you don’t use OneSignal, much of this will apply to you (general configuration). Let’s get to it.
Create React Native App
First thing you’ll need is a React Native app. Maybe that’s your existing app or maybe it’s a new one. We’ll start with a new one. From the command line:
react-native init OneSignalExample
You can access instructions for running on your device at the following links.
Create OneSignal Account & Create App
Next you’ll want to head over to OneSignal and sign up for an account. At that point you’ll be prompted to set up your app.
Now we’ll be asked to configure a platform. This is going to be the most complex part. I’m going to start off with iOS and configure Android later — details on how to do that outlined below.
Generate iOS Push Certificate
So you’re probably sitting at a screen that looks a lot like this…
You may be wanting to jump right into creating your .p12 file (we’ll cover that in a moment) but we’ve got to actually create our app within the Apple Developer portal.
Now if you’ve never done this before it’s important to note that you’ll need to set an Explicit App ID for push notifications to work.
You’re also going to want to enable push notifications for this app.
Now that we’re done with that we can move over to actually creating the provisioning profile. OneSignal has a tool called The Provisionator that will help with this process.
If you’re uncomfortable using giving this tool access to your Apple account you can create the profile manually.
Protip: If you’ve got two-factor authentication turned on for your account you’ll need to turn it off in order to use The Provisionator. Feel free to change your password before/after using it — that’s what I did to aid in keeping my account secure.
Okay, now that we’re past those notes let’s actually use this tool and get our profile.
You’ll want to sign into your account and make sure you choose the proper team.
Upon pressing “Next”, and waiting a few seconds, you’ll see something like this
Go ahead and download those files and remember the password for the p12 file. Then we can head back to OneSignal and upload our file…
And that’s it, for now! We’ll just close out this modal and come back to the React Native side of things in a moment. Now let’s configure Android (it’s easier, I promise).
Generate Google Server API Key
To set up OneSignal with Google we need to go to our App Settings (within OneSignal) and click “Configure” for Android.
We then see that we’ll need a Google Server API Key and a Google Project Number. Let’s get both of those…
You’ll need to go to the Google Services Wizard to do this — the names aren’t important. Just choose things that make sense OR if you’re setting this up with an existing app, make sure you choose the right app.
Then enable Cloud Messaging
Once enabled you’ll have access to your API key and your project ID (called Sender ID). Bring these over to OneSignal.
Woohoo! Platforms are set up. Now we can actually work on integrating this with our app.
OneSignal has a package on npm, react-native-onesignal, that makes integrating with your platform super easy. It’s not the easiest to install but once it’s done you don’t have to do it again :) I’m hoping in the future that they integrate with rnpm/react-native link so that we can minimize diving into native code but until then we must. For now, from your project root, run the following to install the package.
npm install react-native-onesignal --save
Into the Objective-C/Java!
Before I dive in here I want to say that this is basically just me rehashing the official instructions so if you run into issues be sure to check those out as well. With that, let’s jump into our app and start configuring things.
First thing we have to do is install the OneSignal iOS SDK — which is available via CocoaPods. You’ll want to make sure you’ve got at least version 1.1.0. You can check that by running
If it’s outdated you can update with
sudo gem install cocoapods --pre
Now, from within your React Native project, you’ll want to to move to your ios/ directory and initialize a PodFile.
cd ios/ && pod init
You then want to add the OneSignal pod to the file. It should look something like this
Now, back at the command line and still in the ios/ directory, run
Since we’re using CocoaPods a .xcworkspace file will be generated. You’ll want to run the app using that from now on.
Protip: To make sure you always do that add an npm script to your app and use that to open the ios project. Like this one.
Now let’s configure our capabilities within Xcode
Next we need to add the RCTOneSignal.xcodeproj to our Libraries folder. That can be found in /node_modules/react-native-onesignal/ios.
Now we have to add libRCTOneSignal.a to Link Binary with Libraries, which can be found under the Build Phases tab. Just drag it from the left to that section.
Okay, jump over to the Build Settings tab and search for “Header Search Paths”, double click the value, then click the “+” sign. Then add $(SRCROOT)/../node_modules/react-native-onesignal and set it to “recursive”.
Now to our app! We’ll need to make some changes to ios/APP_NAME/AppDelegate.m.
First #import “RCTOneSignal.h”. Then we need to synthesize oneSignal.
Still in your AppDelegate.m you need to setup oneSignal, that’s the first section of code I added below. Make sure to swap “YOUR_ONESIGNAL_APP_ID” with the right ID. The last part is so that you can receive notifications.
You can find your OneSignal App ID via App Settings > Keys & IDs
Jump over to AppDelegate.h and add #import <RCTOneSignal.h> and @property (strong, nonatomic) RCTOneSignal* oneSignal;
Now we’ll want to try and get this to run. You might have to do a few more things here.
Make sure to set your Bundle Identifier to the one you set up when you made the app.
Then we need to make sure we create a provisioning profile that will work with the push certificate we set up earlier. You’ll likely need to create an AdHoc one if you’ve been following these instructions exactly.
Then choose the correct app.
Then choose your certificate and the devices that should be included for the AdHoc distribution. If you need to add devices you can do so on the Apple dev portal. Need to find out your UDID? Use this resource.
Then create your profile and download it. Once it’s downloaded. Double click it so that it’s installed.
Then in Xcode you’ll want to choose that profile in the Provisioning Profile section.
Okay… now… try to compile it. Cross your fingers. If it worked, congrats!
If not make sure you followed all the steps above. Now for Android.
Now to set up Android! Before we get started I need to note that these instructions assume >= v0.29 of React Native. If you’re still on an earlier version follow these instructions. With that, let’s begin… (it’s easier than iOS)
First we need to add some necessary permissions to AndroidManifest.xml, which can be found at android/app/src/main/AndroidManifest.xml.
Now we bounce over to gradle-wrapper.properties, accessible at android/gradle/wrapper/gradle-wrapper.properties to change our distributionUrl. It should end up looking like this (we need gradle 2.10)
Now we tell the Android app about the OneSignal package in settings.gradle (android/settings.gradle).
We also want to update the gradle version we’re using in android/build.gradle — check out line 8.
Note the file that we’re updating now, it’s NOT the same one we just did. We need to tell OneSignal about our app information. Make sure to use your own values for this. In android/app/build.gradle upgrade buildToolsVersion to 23.0.2., add our keys (see code snippet), and add the package as a dependency of our Android app.
Remember, you want to change YOUR_ONESIGNAL_ID (same one used for iOS) and YOUR_GOOGLE_PROJECT_NUMBER (this is the one you generated and added to the OneSignal dashboard earlier).
The full file is available also if you want to reference it. The changes made occur at line 87, line 98, and line 135.
Just about there! Last thing we need to do is modify MainApplication.java (android/app/src/main/java/com/YOUR_APP_NAME/MainApplication.java). Line 15 and 29 are the ones you’ll be interested in.
Hey that was pretty smooth, wasn’t it? Go ahead and make sure your app compiles, I’ll wait.
Good? Good, great. Let’s use these fancy remote notifications now.
Android Usage & iOS Usage
First thing we want to do is create a new App.js file in the root of our project — this way we can write the same code for both iOS and Android. Go ahead and copy and paste the following.
And then change both index.ios.js and index.android.js to the following (so we use the App file we just made).
Okay, now we can go ahead and actually configure OneSignal to work for us. Ready? It’s just two lines (yeah all that for two lines). First we import the package then we call the configure method.
We can then go ahead and refresh or start our app on both iOS and Android. If everything worked as expected you should see something like this on your OneSignal dashboard.
Go ahead and lock the device and jump over to OneSignal’s dashboard and send a message.
I won’t go over all the options available to you through OneSignal (right now) but there is quite a lot you can do through the dashboard. You can also interact with the service via their REST API so you can programmatically send notifications. Anyways, if everything worked out correctly you should have gotten notifications on your device!
Now that’s pretty basic and you can do a lot more with OneSignal and push notifications in general, some of which I’ll cover below.
[iOS] Request notification permission only when needed
One pattern that is encouraged by Apple (I can’t find the docs stating this but they do exist) is to request permission to send push notifications when it’s needed. So, rather than requesting permission as soon as the app boots (the default) you wait until the user takes some action so that they would understand why you’re requesting permission. This builds confidence with your user so let’s set that up.
First thing we have to do is disable auto registration, which we’ll do in the AppDelegate.m file. Remember that self.oneSignal from earlier? We’ll be touching that again.
So once we do that it won’t ask permission — we have to do that manually. OneSignal makes that easy for us. Over in the App.js file we’ll add a button (only on iOS) to request permission. We’re going to use the registerForPushNotifications function to do so. After requesting permission it will do everything necessary to register the device with OneSignal.
If you previously ran the app on your phone you may have to delete it and reinstall so that you’re prompted to enable notifications again.
In App Notification
So let’s say your user gets a notification while they’re in the app and you want to show them that. With OneSignal you can easily show that to them by setting
in your App.js file. This will show a modal with your notification in it while the user is in your app. Simple and useful, right? I thought so.
I think that’s all for me today. This was a monster to write. Want to see more on Push Notifications via OneSignal? Let me know by responding to and recommending this article. I would really appreciate it! Feel free to ask questions below — this can be tricky.
This post is a part of a larger goal to educate as many people as possible about React Native. Interested in learning more? Sign up for my email list and I promise to deliver a ton of valuable React Native knowledge!
Some of the links in the post are affiliate links and I may earn a small commission if you buy something from them.