Skip to content

Modus-Logo-Long-BlackCreated with Sketch.

  • Services
  • Work
  • Blog
  • Resources

    OUR RESOURCES

    Innovation Podcast

    Explore transformative innovation with industry leaders.

    Guides & Playbooks

    Implement leading digital innovation with our strategic guides.

    Practical guide to building an effective AI strategy
  • Who we are

    Our story

    Learn about our values, vision, and commitment to client success.

    Open Source

    Discover how we contribute to and benefit from the global open source ecosystem.

    Careers

    Join our dynamic team and shape the future of digital transformation.

    How we built our unique culture
  • Let's talk
  • EN
  • FR

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,
  });
}
gist: registerForPushNotifications.js



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',
  });
}
gist: SendPushNotification.js



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 OR npm 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!

Posted in Application Development
Share this

Trevor Brindle

Trevor Brindle is a Senior Front End Engineer at Modus Create. He has an avid interest in React Native, music, party parrots, open source software, and automating all the things. He enjoys mentoring new developers and speaking at conferences about JavaScript, Hybrid Development, and Continuous Integration. Trevor lives and goofs around in North Carolina with his wife and daughter.
Follow

Related Posts

  • React Native - React.js Goes Mobile
    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
    Make the Enterprise Mobile Pivot

    Learn Internally and Scale Externally Don't wait until Prom Night to learn how to dance.…

Want more insights to fuel your innovation efforts?

Sign up to receive our monthly newsletter and exclusive content about digital transformation and product development.

What we do

Our services
AI and data
Product development
Design and UX
IT modernization
Platform and MLOps
Developer experience
Security

Our partners
Atlassian
AWS
GitHub
Other partners

Who we are

Our story
Careers
Open source

Our work

Our case studies

Our resources

Blog
Innovation podcast
Guides & playbooks

Connect with us

Get monthly insights on AI adoption

© 2025 Modus Create, LLC

Privacy PolicySitemap
Scroll To Top
  • Services
  • Work
  • Blog
  • Resources
    • Innovation Podcast
    • Guides & Playbooks
  • Who we are
    • Our story
    • Careers Old
  • Let’s talk
  • EN
  • FR