Chapter 7 of 12 ~20 min read

Push Notifications & Background Tasks

Replacing phonegap-plugin-push with expo-notifications, notification channels, Android 13+ POST_NOTIFICATIONS.


1. The Push Notification Pipeline in React Native

In Cordova, configuring phonegap-plugin-push required manual google-services.json placement inside generated platforms that were easily wiped. With Expo Notifications, device push tokens, notification channels (mandatory for Android 8+), and permission modals are handled gracefully in code.

React Native / Expo Push Registration Hook
import * as Notifications from 'expo-notifications';
import * as Device from 'expo-device';
import { Platform } from 'react-native';

// Set notification presentation behavior in foreground
Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: false,
  }),
});

export async function registerForPushNotificationsAsync(): Promise<string | undefined> {
  if (!Device.isDevice) {
    console.warn('Push notifications require a physical device');
    return;
  }

  // 1. Android Notification Channel (Mandatory)
  if (Platform.OS === 'android') {
    await Notifications.setNotificationChannelAsync('default', {
      name: 'Default App Notifications',
      importance: Notifications.AndroidImportance.MAX,
      vibrationPattern: [0, 250, 250, 250],
      lightColor: '#087ea4',
    });
  }

  // 2. Runtime Permissions (Android 13+ & iOS)
  const { status: existingStatus } = await Notifications.getPermissionsAsync();
  let finalStatus = existingStatus;
  if (existingStatus !== 'granted') {
    const { status } = await Notifications.requestPermissionsAsync();
    finalStatus = status;
  }
  if (finalStatus !== 'granted') {
    alert('Failed to get push notification token permissions!');
    return;
  }

  // 3. Obtain Token
  const token = (await Notifications.getExpoPushTokenAsync()).data;
  console.log('Push Token:', token);
  return token;
}