Skip to main content
React Native Introduction
CHAPTER 23 Beginner

Push Notifications in React Native

Updated: May 16, 2026
7 min read

# CHAPTER 23

Push Notifications in React Native

1. Introduction

The most powerful tool for user retention is the Push Notification. When an app is closed and the phone is locked, a notification is the only way to pull the user back into your ecosystem. Historically, configuring the Apple Push Notification service (APNs) and Firebase Cloud Messaging (FCM) required managing complex native certificates. Expo revolutionized this by providing a unified, cross-platform notification service. In this chapter, we will master Push Notifications in React Native. We will request user permissions, generate a unique Push Token, and trigger both Local and Remote notifications using expo-notifications.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Install and configure expo-notifications.
  • Differentiate between Local and Remote push notifications.
  • Request explicit Notification permissions from the OS.
  • Retrieve the device's unique Expo Push Token.
  • Trigger an immediate Local Notification.

3. Local vs Remote Notifications

  • Local Notifications: The app itself triggers the alert based on a timer (e.g., an alarm clock app or a daily reminder). No internet required.
  • Remote Push Notifications: A backend server (like Node.js) sends a message to Apple/Google's servers, which beams the alert down to the specific phone over the internet (e.g., "Bob liked your post!").

4. Installation and Setup

Run the following command to install the Expo Notifications package:
bash
1
npx expo install expo-notifications

First, we must configure how the app behaves when a notification arrives while the user is actively using the app (foreground).

javascript
12345678910
import * as Notifications from 'expo-notifications';

// Tells the OS to show a popup alert and play a sound even if the app is open!
Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: false,
  }),
});

5. Triggering a Local Notification

Let's build a button that schedules a reminder to pop up on the screen 5 seconds after it is pressed.
javascript
1234567891011121314151617181920212223242526
import React from 'react';
import { View, Button } from 'react-native';
import * as Notifications from 'expo-notifications';

export default function ReminderScreen() {
  
  const scheduleNotification = async () => {
    // Call the scheduling API
    await Notifications.scheduleNotificationAsync({
      content: {
        title: "Pizza is ready! 🍕",
        body: "Take it out of the oven before it burns.",
        data: { recipeId: 42 }, // Hidden data payload!
      },
      trigger: { seconds: 5 }, // Fire 5 seconds from now
    });
    
    alert("Notification scheduled!");
  };

  return (
    <View style={{ flex: 1, justifyContent: &#039;center&#039;, alignItems: &#039;center&#039; }}>
      <Button title="Remind me in 5 seconds" onPress={scheduleNotification} />
    </View>
  );
}

6. The Holy Grail: Remote Push Notifications

To send a message from a server to a specific phone, the server needs to know the phone's "address." This address is called a Push Token. To get this token, you must execute a strict, 3-step workflow on App Launch:
  1. 1. Ask the OS for permission to send notifications.
  1. 2. If granted, ask Expo to generate the Push Token.
  1. 3. Save that token to your database (Firestore) attached to the user's profile.
javascript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
import { useEffect, useState } from &#039;react&#039;;
import * as Notifications from &#039;expo-notifications&#039;;
import { Platform } from &#039;react-native&#039;;

export default function App() {
  const [expoPushToken, setExpoPushToken] = useState(&#039;&#039;);

  useEffect(() => {
    registerForPushNotificationsAsync().then(token => {
      setExpoPushToken(token);
      console.log("MY TOKEN:", token); // Send this to your backend!
    });
  }, []);

  async function registerForPushNotificationsAsync() {
    let token;
    
    // 1. Check existing permissions
    const { status: existingStatus } = await Notifications.getPermissionsAsync();
    let finalStatus = existingStatus;
    
    // 2. If not granted, prompt the user with a popup!
    if (existingStatus !== &#039;granted&#039;) {
      const { status } = await Notifications.requestPermissionsAsync();
      finalStatus = status;
    }
    
    // 3. If they hit "Deny", stop execution.
    if (finalStatus !== &#039;granted&#039;) {
      alert(&#039;Failed to get push token for push notification!&#039;);
      return;
    }
    
    // 4. Success! Fetch the unique token.
    token = (await Notifications.getExpoPushTokenAsync()).data;
    
    // Android requires setting up a Notification Channel
    if (Platform.OS === &#039;android&#039;) {
      Notifications.setNotificationChannelAsync(&#039;default&#039;, {
        name: &#039;default&#039;,
        importance: Notifications.AndroidImportance.MAX,
      });
    }

    return token;
  }
}

7. Testing Remote Notifications

Expo provides a brilliant tool to test notifications without writing backend server code.
  1. 1. Copy the ExponentPushToken[xxxxx] generated in your console from the code above.
  1. 2. Open your web browser and go to: expo.dev/notifications
  1. 3. Paste your token into the tool, type a title and message, and hit Send Notification.
  1. 4. Lock your physical phone screen. The notification will instantly buzz your device over the internet!

8. Visual Learning: The Remote Architecture

txt
12345678910
[ Your Node.js Server ]
      | (Sends Title, Body, and target Push Token)
      v
[ Expo Notification Servers ]
      | (Translates request to Apple/Google format)
      |
    /   \
(APNs)  (FCM)
   |      |
[ iOS ] [ Android ]

9. Common Mistakes

  • Testing on Emulators: Push notifications rely heavily on physical device hardware IDs. While Android emulators *can* sometimes receive notifications, iOS Simulators cannot receive remote push notifications at all. You MUST test this feature using the Expo Go app on a physical iPhone or Android device.

10. Best Practices

  • Handling Taps: When a user taps a notification on their lock screen, your app opens. You should use the addNotificationResponseReceivedListener API to intercept the notification payload, read the hidden data: { recipeId: 42 } object, and automatically route the user directly to the Details Screen for recipe 42!

11. Practice Exercises

  1. 1. What Expo API method is utilized to schedule an offline alarm to trigger on the device exactly 10 minutes from execution?
  1. 2. What unique alphanumeric string must be generated on the device and transmitted to your backend database to enable remote server-to-device messaging?

12. MCQs with Answers

Question 1

Before an application can generate an Expo Push Token to receive remote notifications, what critical operating system requirement must be fulfilled?

Question 2

A developer uses the Expo Notification Tool to send a remote message. The message successfully arrives on an Android phone, but does not appear on an iOS Simulator running on a Mac. Why?

13. Interview Questions

  • Q: Contrast the architectural execution and network requirements of Local Notifications versus Remote Push Notifications.
  • Q: Explain the purpose of the unified Expo Push Notification service. How does it simplify the traditional fragmentation between Apple APNs and Firebase Cloud Messaging (FCM)?
  • Q: Describe the UX/Routing pattern known as "Deep Linking via Notification." How does the hidden data payload enable this flow when a user interacts with a lock screen alert?

14. FAQs

Q: Do I have to use Expo's servers to send notifications when I publish my app? A: No. While the Expo API is the easiest, you can completely eject and use standard Firebase Cloud Messaging (FCM) or OneSignal native libraries if your company already utilizes those infrastructures.

15. Summary

In Chapter 23, we unlocked the most critical tool for mobile user re-engagement. We integrated expo-notifications, configuring foreground handlers to ensure alerts display seamlessly. We bypassed network requirements by scheduling Local Notifications using timers. More importantly, we conquered the complex permissions pipeline required to extract a cryptographic Expo Push Token, tested it via the Expo Cloud, and established the precise architecture required to execute global Remote Push Notifications.

16. Next Chapter Recommendation

Our app can talk to the server, but it can't interact with the physical world around the user. Let's tap into the device's hardware sensors. Proceed to Chapter 24: Camera, Gallery, and Device Features.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·