push-notifications

timequity's avatarfrom timequity

Firebase Cloud Messaging and Apple Push Notification Service setup.

⭐0stars🔀0forks📁View on GitHub🕐Updated Dec 18, 2025

When & Why to Use This Skill

This Claude skill provides a comprehensive guide and boilerplate code for integrating Firebase Cloud Messaging (FCM) and Apple Push Notification Service (APNs) into mobile applications. It simplifies the complex setup process for Expo and React Native environments, covering permission requests, token generation, and both foreground and background notification handling to enhance user engagement.

Use Cases

  • Case 1: Implementing real-time push notifications in a cross-platform Expo or React Native mobile application.
  • Case 2: Configuring secure permission workflows to request and manage notification access on iOS and Android devices.
  • Case 3: Setting up backend-to-frontend communication using the Expo Push API to send targeted alerts to specific users.
  • Case 4: Handling deep linking by navigating users to specific screens within the app based on notification data payloads.
namepush-notifications
descriptionFirebase Cloud Messaging and Apple Push Notification Service setup.

Push Notifications

Expo Notifications

npx expo install expo-notifications expo-device
import * as Notifications from 'expo-notifications';
import * as Device from 'expo-device';

// Configure
Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: true,
  }),
});

// Request permission
async function registerForPushNotifications() {
  if (!Device.isDevice) return null;

  const { status: existingStatus } = await Notifications.getPermissionsAsync();
  let finalStatus = existingStatus;

  if (existingStatus !== 'granted') {
    const { status } = await Notifications.requestPermissionsAsync();
    finalStatus = status;
  }

  if (finalStatus !== 'granted') return null;

  const token = await Notifications.getExpoPushTokenAsync({
    projectId: 'your-project-id',
  });

  return token.data;
}

Handle Notifications

// Foreground
useEffect(() => {
  const subscription = Notifications.addNotificationReceivedListener(
    (notification) => {
      console.log('Received:', notification);
    }
  );

  return () => subscription.remove();
}, []);

// Tap response
useEffect(() => {
  const subscription = Notifications.addNotificationResponseReceivedListener(
    (response) => {
      const data = response.notification.request.content.data;
      // Navigate based on data
      navigation.navigate(data.screen, data.params);
    }
  );

  return () => subscription.remove();
}, []);

Backend Integration

// Send from server
await fetch('https://exp.host/--/api/v2/push/send', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    to: expoPushToken,
    title: 'New message',
    body: 'You have a new message',
    data: { screen: 'Chat', chatId: '123' },
  }),
});

Firebase (bare workflow)

import messaging from '@react-native-firebase/messaging';

// Get FCM token
const fcmToken = await messaging().getToken();

// Background handler
messaging().setBackgroundMessageHandler(async (message) => {
  console.log('Background message:', message);
});