Expo Server SDK for Node.js

6.1.0 · active · verified Sun Apr 19

The `expo-server-sdk` is a server-side library for Node.js environments, designed to facilitate the sending of push notifications to mobile applications built with Expo. It provides utilities for constructing push notification messages, sending them efficiently to Expo's push notification service, and handling the resulting receipts and errors. The current stable version is 6.1.0. This SDK maintains an active release cadence, with recent major versions (v4, v5, v6) introducing significant breaking changes around module systems and Node.js version support. Key differentiators include its tight integration with the Expo ecosystem, simplifying the complex process of managing push tokens and batching messages, and providing a streamlined API for interacting with the Expo push service. It abstracts away much of the underlying HTTP request handling and error parsing.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates initializing the Expo client, validating an Expo push token, constructing a push notification message, chunking and sending messages, and finally retrieving and processing push notification receipts to check for delivery status and errors.

import { Expo, ExpoPushMessage, ExpoPushTicket, ExpoPushReceiptId } from 'expo-server-sdk';

const expo = new Expo();

const sendPushNotification = async (token: string, message: string, data?: object) => {
  if (!Expo.isExpoPushToken(token)) {
    console.error(`Push token ${token} is not a valid Expo push token.`);
    return;
  }

  const messages: ExpoPushMessage[] = [{
    to: token,
    sound: 'default',
    body: message,
    data: data || { withSome: 'data' },
    channelId: 'default',
  }];

  const chunks = expo.chunkPushNotifications(messages);
  const tickets: ExpoPushTicket[] = [];

  for (const chunk of chunks) {
    try {
      const ticketChunk = await expo.sendPushNotificationsAsync(chunk);
      tickets.push(...ticketChunk);
      console.log('Push tickets received:', ticketChunk);
    } catch (error) {
      console.error('Error sending push chunk:', error);
    }
  }

  const receiptIds: ExpoPushReceiptId[] = [];
  for (const ticket of tickets) {
    if (ticket.id) {
      receiptIds.push(ticket.id);
    }
  }

  if (receiptIds.length > 0) {
    const receiptIdChunks = expo.chunkPushReceiptIds(receiptIds);
    for (const chunk of receiptIdChunks) {
      try {
        const receipts = await expo.getPushNotificationReceiptsAsync(chunk);
        console.log('Push receipts received:', receipts);

        for (const receiptId in receipts) {
          const { status, message, details } = receipts[receiptId];
          if (status === 'error') {
            console.error(`There was an error sending a notification: ${message}`);
            if (details && details.error) {
              console.error(`The error code is ${details.error}`);
            }
          }
        }
      } catch (error) {
        console.error('Error getting push receipts:', error);
      }
    }
  }
};

// Example usage (replace with actual token and message)
const exampleToken = process.env.EXPO_PUSH_TOKEN ?? 'ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]';
if (exampleToken) {
  sendPushNotification(exampleToken, 'Hello from Expo!', { 'foo': 'bar' });
}

view raw JSON →