1--- 2title: Push notifications setup 3sidebar_title: Setup 4description: Learn how to setup push notifications, get credentials for development and production, and test sending push notifications. 5--- 6 7import { Terminal } from '~/ui/components/Snippet'; 8import { Step } from '~/ui/components/Step'; 9import ImageSpotlight from '~/components/plugins/ImageSpotlight'; 10import { BoxLink } from '~/ui/components/BoxLink'; 11 12To 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. 13 14To get the client-side ready for push notifications, the following things are required: 15 16- The user's permission to send them push notifications. 17- The user's [`ExpoPushToken`](/versions/latest/sdk/notifications/#expopushtoken). 18 19## Prerequisites 20 21The 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/). 22 23<Step label="1"> 24 25## Install libraries 26 27Run the following command to install the `expo-notifications`, `expo-device` and `expo-constants` libraries: 28 29<Terminal cmd={['$ npx expo install expo-notifications expo-device expo-constants']} /> 30 31- [`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. 32- [`expo-device`](/versions/latest/sdk/device) is used to check whether the app is running on a physical device. 33- [`expo-constants`](/versions/latest/sdk/constants) is used to get the `projectId` value from the app config. 34 35</Step> 36 37<Step label="2"> 38 39## Add a minimal working example 40 41The 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: 42 43```jsx App.js 44import { useState, useEffect, useRef } from 'react'; 45import { Text, View, Button, Platform } from 'react-native'; 46import * as Device from 'expo-device'; 47import * as Notifications from 'expo-notifications'; 48import Constants from "expo-constants"; 49 50/* @info This handler determines how your app handles notifications that come in while the app is foregrounded. */ 51Notifications.setNotificationHandler({ 52 handleNotification: async () => ({ 53 shouldShowAlert: true, 54 shouldPlaySound: false, 55 shouldSetBadge: false, 56 }), 57}); 58/* @end */ 59 60// Can use this function below or use Expo's Push Notification Tool from: https://expo.dev/notifications 61async function sendPushNotification(expoPushToken) { 62 const message = { 63 to: expoPushToken, 64 sound: 'default', 65 title: 'Original Title', 66 body: 'And here is the body!', 67 data: { someData: 'goes here' }, 68 }; 69 70 await fetch('https://exp.host/--/api/v2/push/send', { 71 method: 'POST', 72 headers: { 73 Accept: 'application/json', 74 'Accept-encoding': 'gzip, deflate', 75 'Content-Type': 'application/json', 76 }, 77 body: JSON.stringify(message), 78 }); 79} 80 81async function registerForPushNotificationsAsync() { 82 let token; 83 /* @info You should make sure the app is running on a physical device since push notifications don't work on an emulator/simulator. */ 84 if (Device.isDevice) { 85 /* @end */ 86 const { status: existingStatus } = await Notifications.getPermissionsAsync(); 87 let finalStatus = existingStatus; 88 if (existingStatus !== 'granted') { 89 const { status } = await Notifications.requestPermissionsAsync(); 90 finalStatus = status; 91 } 92 if (finalStatus !== 'granted') { 93 alert('Failed to get push token for push notification!'); 94 return; 95 } 96 /* @info This provides the ExpoPushToken which is attributed based on the ID of the project. */ 97 token = ( 98 await Notifications.getExpoPushTokenAsync({ 99 projectId: Constants.expoConfig.extra.eas.projectId, 100 }) 101 /* @end */ 102 console.log(token); 103 } else { 104 alert('Must use physical device for Push Notifications'); 105 } 106 107 /* @info On Android, you need to specify a channel. */ 108 if (Platform.OS === 'android') { 109 Notifications.setNotificationChannelAsync('default', { 110 name: 'default', 111 importance: Notifications.AndroidImportance.MAX, 112 vibrationPattern: [0, 250, 250, 250], 113 lightColor: '#FF231F7C', 114 }); 115 } 116 /* @end */ 117 118 return token; 119} 120 121export default function App() { 122 const [expoPushToken, setExpoPushToken] = useState(''); 123 const [notification, setNotification] = useState(false); 124 const notificationListener = useRef(); 125 const responseListener = useRef(); 126 127 useEffect(() => { 128 registerForPushNotificationsAsync().then(token => setExpoPushToken(token)); 129 130 /* @info This listener is fired whenever a notification is received while the app is foregrounded. */ 131 notificationListener.current = Notifications.addNotificationReceivedListener(notification => { 132 setNotification(notification); 133 }); 134 /* @end */ 135 136 /* @info This listener is fired whenever a user taps on or interacts with a notification (works when an app is foregrounded, backgrounded, or killed). */ 137 responseListener.current = Notifications.addNotificationResponseReceivedListener(response => { 138 console.log(response); 139 }); 140 /* @end */ 141 142 return () => { 143 Notifications.removeNotificationSubscription(notificationListener.current); 144 Notifications.removeNotificationSubscription(responseListener.current); 145 }; 146 }, []); 147 148 return ( 149 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'space-around' }}> 150 <Text>Your expo push token: {expoPushToken}</Text> 151 <View style={{ alignItems: 'center', justifyContent: 'center' }}> 152 <Text>Title: {notification && notification.request.content.title} </Text> 153 <Text>Body: {notification && notification.request.content.body}</Text> 154 <Text>Data: {notification && JSON.stringify(notification.request.content.data)}</Text> 155 </View> 156 <Button 157 title="Press to Send Notification" 158 onPress={async () => { 159 await sendPushNotification(expoPushToken); 160 }} 161 /> 162 </View> 163 ); 164} 165``` 166 167### Configure `projectId` 168 169Using the previous example, when you are registering for push notifications, you need to use [`projectId`](/versions/latest/sdk/constants/#easconfig). This property is used to attribute Expo push token to the specific project. For projects using EAS, the `projectId` property represents the Universally Unique Identifier (UUID) of that project. 170 171`projectId` is automatically set when you create a development build. However, **we recommend setting it manually in your project's code**. To do so, you can use [`expo-constants`](/versions/latest/sdk/constants/) to get the `projectId` value from the app config. 172 173```js 174token = await Notifications.getExpoPushTokenAsync({ 175 projectId: Constants.expoConfig.extra.eas.projectId, 176}); 177``` 178 179One advantage of attributing the Expo push token to your project's ID is that it doesn't change when a project is transferred between different accounts or the existing account gets renamed. 180 181</Step> 182 183<Step label="3"> 184 185## Get Credentials for development builds 186 187For Android and iOS, there are different requirements to set up your credentials. 188 189### Android 190 191For Android, you need to configure **Firebase Cloud Messaging (FCM)** to get your credentials and set up your Expo project. It is required for all Android apps using Expo SDK. 192 193> **warning** FCM is not currently available for `expo-notifications` on iOS. 194 195#### Setting up FCM 196 1971. To create a Firebase project, go to the [Firebase console](https://console.firebase.google.com/) and click on **Add project**. 198 1992. In the console, click the setting icon next to **Project overview** and open **Project settings**. Then, under **Your apps**, click the Android icon to open **Add Firebase to your Android app** and follow the steps. **Make sure that the Android package name you enter is the same as the value of `android.package` from your app.json.** 200 2013. After registering the app, download the **google-services.json** file and place it in your project's root directory. 202 203 > The **google-services.json** file contains unique and non-secret identifiers of your Firebase project. For more information, see [Understand Firebase Projects](https://firebase.google.com/docs/projects/learn-more#config-files-objects). 204 2054. In **app.json**, add an `android.googleServicesFile` field with the relative path to the downloaded **google-services.json** file. If you placed it in the root directory, the path is: 206 207 ```json app.json 208 { 209 "android": { 210 "googleServicesFile": "./google-services.json" 211 } 212 } 213 ``` 214 2155. For push notifications to work correctly, Firebase requires the API key to either be unrestricted (the key can call any API) or have access to both **Firebase Cloud Messaging API** and **Firebase Installations API**. The API key is found under the `client.api_key.current_key` field in **google-services.json** file: 216 217 ```json google-services.json 218 { 219 "client": [ 220 { 221 "api_key": [ 222 { 223 "current_key" "<your Google Cloud Platform API key>", 224 } 225 ] 226 } 227 ] 228 } 229 ``` 230 2316. Firebase also creates an API key in the Google Cloud Platform Credentials console with a name like **Android key (auto-created by Firebase)**. This could be a different key than the one found in **google-services.json**. 232 2337. To be sure that both the `current_key` and the **Android key** in the Credentials console are the same, go to the [Google Cloud API Credentials console](https://console.cloud.google.com/apis/credentials) and click on **Show key** to verify their value. It will be marked as **unrestricted**. 234 235 > Firebase projects with multiple Android apps might contain duplicated data under the `client` array in the **google-services.json**. This can cause issues when the app is fetching the push notification token. **Make sure to only have one client object with the correct keys and metadata in google-services.json**. 236 237Now you can re-build the development build using the `eas build` command. At this point, if you need to create a development build, see [create a development build for a device](/develop/development-builds/create-a-build/#create-a-development-build-for-the-device). 238 239#### Upload server credentials 240 241For Expo to send push notifications from our servers and use your credentials, you'll have to upload your secret server key to your project's Expo dashboard. 242 2431. In the Firebase console, next to **Project overview**, click gear icon to open **Project settings**. 244 2452. Click on the **Cloud Messaging** tab in the Settings pane. 246 2473. Copy the token listed next to the **Server key**. 248 249 > Server Key is only available in **Cloud Messaging API (Legacy)**, which is disabled by default. <br/> Enable it by clicking the three-dot menu > **Manage API in Google Cloud Console** and following the steps in the console. Once the legacy messaging API is enabled, you should see Server Key in that section. 250 251 <ImageSpotlight 252 alt="Getting the server key from Firebase console's Cloud messaging tab." 253 src="/static/images/notifications/server-key-from-fcm.jpg" 254 style={{ maxWidth: 760 }} 255 /> 256 2574. In your [Expo account's](https://expo.dev/) dashboard, select your project, and click on **Credentials** in the navigation menu. Then, click on your **Application Identifier** that follows the pattern: `com.company.app`. 258 2595. Under **Service Credentials** > **FCM Server Key**, click **Add a FCM Server Key** > **Google Cloud Messaging Token** and add the **Server key** from **step 3**. 260 261> Expo Notifications only supports the **Cloud Messaging API (Legacy)** key at this time. This key is deprecated by Firebase. However, it will continue to work until June 30, 2024. We will provide information on migrating to the new v1 key in the future. 262 263### iOS 264 265> **warning** A paid Apple Developer Account is required to generate credentials. 266 267For iOS, make sure you have [registered your iOS device](/develop/development-builds/create-a-build/#create-a-development-build-for-the-device) on which you want to test before running the `eas build` command for the first time. 268 269If you create a development build for the first time, you'll be asked to enable push notifications. Answer yes to the following questions when prompted by the EAS CLI: 270 271- Setup Push Notifications for your project 272- Generating a new Apple Push Notifications service key 273 274<br /> 275 276> If you are not using EAS Build, run `eas credentials` manually. 277 278</Step> 279 280<Step label="4"> 281 282## Test using the push notifications tool 283 284After creating and installing the development build, you can use [Expo's push notifications tool](https://expo.dev/notifications) to quickly send a test notification to your device. 285 2861. Start the development server for your project: 287 288 <Terminal cmd={['$ npx expo start --dev-client']} /> 289 2902. Open the development build on your device. 291 2923. After the `ExpoPushToken` is generated, enter the value in the Expo push notifications tool with other details (for example, a message title and body). 293 2944. Click on the **Send a Notification** button. 295 296<ImageSpotlight 297 alt="Expo push notifications tool overview." 298 src="/static/images/notifications/push-notifications-tool-overview.png" 299 style={{ maxWidth: 1200 }} 300/> 301 302After sending the notification from the tool, you should see the notification on your device. Below is an example of an Android device receiving a push notification. 303 304<ImageSpotlight 305 alt="An Android device receiving a push notification." 306 src="/static/images/notifications/notification-on-android.png" 307 style={{ maxWidth: 360 }} 308/> 309 310</Step> 311 312## Next step 313 314<BoxLink 315 title="Send notifications using Expo's Push API" 316 description="Learn how to set your back-end using Expo's Push API, implementation practices, common errors and security best practices." 317 href="/push-notifications/sending-notifications" 318/> 319