--- title: Push notifications setup sidebar_title: Setup description: Learn how to setup push notifications, get credentials for development and production, and test sending push notifications. --- import { Terminal } from '~/ui/components/Snippet'; import { Step } from '~/ui/components/Step'; import ImageSpotlight from '~/components/plugins/ImageSpotlight'; import { BoxLink } from '~/ui/components/BoxLink'; To utilize Expo's push notification service, you must configure your app by installing a set of libraries, implementing functions to handle notifications, and setting up credentials for Android and iOS. Once you have completed the steps mentioned in this guide, you'll be able to test sending and receiving notifications on a device. To get the client-side ready for push notifications, the following things are required: - The user's permission to send them push notifications. - The user's [`ExpoPushToken`](/versions/latest/sdk/notifications/#expopushtoken). ## Prerequisites The following steps described in this guide use [EAS Build](/build/introduction/). However, you can use the `expo-notifications` library without EAS Build by building [your project locally](/workflow/customizing/). ## Install libraries Run the following command to install the `expo-notifications`, `expo-device` and `expo-constants` libraries: - [`expo-notifications`](/versions/latest/sdk/notifications) library is used to request a user's permission and to fetch the `ExpoPushToken`. It is not supported on an Android Emulator or an iOS simulator. - [`expo-device`](/versions/latest/sdk/device) is used to check whether the app is running on a physical device. - [`expo-constants`](/versions/latest/sdk/constants) is used to get the `projectId` value from the app config. ## Add a minimal working example The code below shows a working example of how to register for, send, and receive push notifications in a React Native app. Copy and paste it into your project: ```jsx App.js import { useState, useEffect, useRef } from 'react'; import { Text, View, Button, Platform } from 'react-native'; import * as Device from 'expo-device'; import * as Notifications from 'expo-notifications'; import Constants from "expo-constants"; /* @info This handler determines how your app handles notifications that come in while the app is foregrounded. */ Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldShowAlert: true, shouldPlaySound: false, shouldSetBadge: false, }), }); /* @end */ // Can use this function below or use Expo's Push Notification Tool from: https://expo.dev/notifications async function sendPushNotification(expoPushToken) { const message = { to: expoPushToken, sound: 'default', title: 'Original Title', body: 'And here is the body!', data: { someData: 'goes here' }, }; await fetch('https://exp.host/--/api/v2/push/send', { method: 'POST', headers: { Accept: 'application/json', 'Accept-encoding': 'gzip, deflate', 'Content-Type': 'application/json', }, body: JSON.stringify(message), }); } async function registerForPushNotificationsAsync() { let token; /* @info You should make sure the app is running on a physical device since push notifications don't work on an emulator/simulator. */ if (Device.isDevice) { /* @end */ 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 token for push notification!'); return; } /* @info This provides the ExpoPushToken which is attributed based on the ID of the project. */ token = await Notifications.getExpoPushTokenAsync({ projectId: Constants.expoConfig.extra.eas.projectId, }); /* @end */ console.log(token); } else { alert('Must use physical device for Push Notifications'); } /* @info On Android, you need to specify a channel. */ if (Platform.OS === 'android') { Notifications.setNotificationChannelAsync('default', { name: 'default', importance: Notifications.AndroidImportance.MAX, vibrationPattern: [0, 250, 250, 250], lightColor: '#FF231F7C', }); } /* @end */ return token; } export default function App() { const [expoPushToken, setExpoPushToken] = useState(''); const [notification, setNotification] = useState(false); const notificationListener = useRef(); const responseListener = useRef(); useEffect(() => { registerForPushNotificationsAsync().then(token => setExpoPushToken(token)); /* @info This listener is fired whenever a notification is received while the app is foregrounded. */ notificationListener.current = Notifications.addNotificationReceivedListener(notification => { setNotification(notification); }); /* @end */ /* @info This listener is fired whenever a user taps on or interacts with a notification (works when an app is foregrounded, backgrounded, or killed). */ responseListener.current = Notifications.addNotificationResponseReceivedListener(response => { console.log(response); }); /* @end */ return () => { Notifications.removeNotificationSubscription(notificationListener.current); Notifications.removeNotificationSubscription(responseListener.current); }; }, []); return ( Your expo push token: {expoPushToken} Title: {notification && notification.request.content.title} Body: {notification && notification.request.content.body} Data: {notification && JSON.stringify(notification.request.content.data)}