Push notifications are an integral part of mobile app development these days, but many developers, myself included, cannot even think about implementing them without breaking into a cold sweat. Alright, maybe I’m exaggerating a bit, but I’ve never had fun with them before, until now.
Enter Expo. Expo is an amazing set of tools that vastly simplifies native development on iOS and Android. You don’t need Xcode, Android Studio, or any special hardware. Heck, you don’t even need a USB cable to connect your phone to your computer, and you can still use native features like the vibration API, the device payment API, Push Notifications, and publish your app to the app stores.
Getting Started
To demonstrate notifications, we will use Create React Native App, easily installable via yarn or npm. The following directions are paraphrased from their excellent getting started tutorial. Run either npm install -g create-react-native-app
or yarn global add create-react-native-app
.
To create a new app, run the following command, where “push-demo” is the name of the app, and consequently the directory created.
$ create-react-native-app push-demo $ cd push-demo
To run it on your phone, download the Expo Client app from your app store, then run npm start
or yarn start
, and scan the QR code from your terminal using the Expo app. Voila, a native app, running on your phone.
Register for notifications
The first thing we have to do, now that we have an app initialized, is to deal with registering push notifications. This process gets an app specific device token (special word for unique, scary looking string) from the Apple Push Notification service (APNs) or Google Cloud Messaging (GCM/FCM). However, Expo takes care of most of this for us, and all we have to do is:
async registerForPushNotifications() { const { status } = await Permissions.getAsync(Permissions.NOTIFICATIONS); if (status !== 'granted') { const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS); if (status !== 'granted') { return; } } const token = await Notifications.getExpoPushTokenAsync(); this.subscription = Notifications.addListener(this.handleNotification); this.setState({ token, }); }
This function takes care of the multiple states of permission grants a device can have. You can already have permissions for notifications granted, not yet granted, or declined. Next, it requests a push token from Expo, asynchronously. Then it defines a notification handler, in case the notification is sent while the app is in foreground, and finally it sets the token in the component state for use in the UI and in other functions. Now that we have a device token, we can use that to call Expo’s notification backend, which then calls APNS or GCM.
Send your first push notification
Expo has great documentation for this, but come on, I don’t want to have to set up a server and database just to test push notifications! However, Expo’s docs mention a direct HTTP/2 API, and give a cURL command so letโs try that directly from the device. To achieve this, we can write another function to send a push notification, given a token, title, and body.
sendPushNotification(token = this.state.token, title = this.state.title, body = this.state.body) { return fetch('https://exp.host/--/api/v2/push/send', { body: JSON.stringify({ to: token, title: title, body: body, data: { message: `${title} - ${body}` }, }), headers: { 'Content-Type': 'application/json', }, method: 'POST', }); }
This function uses fetch to POST a JSON body containing the token and message to the Expo server. Combine this with some UI to allow entry of a title and body that you want the notification to display, and some conditionals to show the notification body when it is received, and weโre ready for a test!
The full source code for App.js can be found here.
The app has two buttons: a register and a send button. First, hit the register button and the device token field will show up. Then, hit the send button and your token and body from your input fields will be sent to Expo’s notification server, then to APNS or GCM as needed, and back to your phone using the token. Magic.
No provisioning profiles, certificates, keystores, entitlements, configurations, API keys, native IDEs, extra SDKs, or nightmares.
Where to go next
You can take this proof of concept in a lot of different directions. Thanks to Expo, all of this flow can be done on the device, if your target workflow is simple enough. But the next logical step would be to write a server side device token store. This way you can save the token with user information to be used later. You could even go as far as creating a UI dashboard to send notifications through, and to view and manage your users from.
In summary, all you have to do to get this working is:
$ create-react-native-app push-demo
$ cd push-demo
$ yarn start
ORnpm start
- Copy & paste App.js into your project from here
- Scan the QR code from Expo
- Hit the register button
- Hit the send button
This is just one of the many awesome features provided by Expo, and I encourage you to it check out the rest of its capabilities in the docs, which even include a guide on publishing to the app store. But hey, thatโs another post!
Trevor Brindle
Related Posts
-
React Native - React.js Goes Mobile
<Hello World /> If you are plugged into the world of JavaScript development, no doubt…
-
Make the Enterprise Mobile Pivot
Learn Internally and Scale Externally Don't wait until Prom Night to learn how to dance.…