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 use Expo's push notification service, you need to configure your app to install a set of libraries, add functions to handle notifications and configure credentials for Android and iOS. After going through these steps, you'll be able to test notification 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<Step label="1"> 20 21## Install libraries 22 23Run the following command to install `expo-notifications` and `expo-device` libraries: 24 25<Terminal cmd={['$ npx expo install expo-notifications expo-device']} /> 26 27[`expo-notifications`](/versions/latest/sdk/notifications) library is used to request for a user's permission and to fetch the `ExpoPushToken`. It is not supported on an Android Emulator or an iOS simulator. The [`expo-device`](/versions/latest/sdk/device) is used to check whether the app is running on a physical device. 28 29</Step> 30 31<Step label="2"> 32 33## Add a minimal working example 34 35The 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: 36 37```jsx App.js 38import { useState, useEffect, useRef } from 'react'; 39import { Text, View, Button, Platform } from 'react-native'; 40import * as Device from 'expo-device'; 41import * as Notifications from 'expo-notifications'; 42 43/* @info This handler determines how your app handles notifications that come in while the app is foregrounded. */ 44Notifications.setNotificationHandler({ 45 handleNotification: async () => ({ 46 shouldShowAlert: true, 47 shouldPlaySound: false, 48 shouldSetBadge: false, 49 }), 50}); 51/* @end */ 52 53// Can use this function below OR use Expo's Push Notification Tool from: https://expo.dev/notifications 54async function sendPushNotification(expoPushToken) { 55 const message = { 56 to: expoPushToken, 57 sound: 'default', 58 title: 'Original Title', 59 body: 'And here is the body!', 60 data: { someData: 'goes here' }, 61 }; 62 63 await fetch('https://exp.host/--/api/v2/push/send', { 64 method: 'POST', 65 headers: { 66 Accept: 'application/json', 67 'Accept-encoding': 'gzip, deflate', 68 'Content-Type': 'application/json', 69 }, 70 body: JSON.stringify(message), 71 }); 72} 73 74async function registerForPushNotificationsAsync() { 75 let token; 76 /* @info You should make sure the app is running on a physical device since push notifications don't work on an emulator/simulator. */ 77 if (Device.isDevice) { 78 /* @end */ 79 const { status: existingStatus } = await Notifications.getPermissionsAsync(); 80 let finalStatus = existingStatus; 81 if (existingStatus !== 'granted') { 82 const { status } = await Notifications.requestPermissionsAsync(); 83 finalStatus = status; 84 } 85 if (finalStatus !== 'granted') { 86 alert('Failed to get push token for push notification!'); 87 return; 88 } 89 /* @info This provides the ExpoPushToken. */ 90 token = (await Notifications.getExpoPushTokenAsync()).data; 91 /* @end */ 92 console.log(token); 93 } else { 94 alert('Must use physical device for Push Notifications'); 95 } 96 97 /* @info On Android, you need to specify a channel. */ 98 if (Platform.OS === 'android') { 99 Notifications.setNotificationChannelAsync('default', { 100 name: 'default', 101 importance: Notifications.AndroidImportance.MAX, 102 vibrationPattern: [0, 250, 250, 250], 103 lightColor: '#FF231F7C', 104 }); 105 } 106 /* @end */ 107 108 return token; 109} 110 111export default function App() { 112 const [expoPushToken, setExpoPushToken] = useState(''); 113 const [notification, setNotification] = useState(false); 114 const notificationListener = useRef(); 115 const responseListener = useRef(); 116 117 useEffect(() => { 118 registerForPushNotificationsAsync().then(token => setExpoPushToken(token)); 119 120 /* @info This listener is fired whenever a notification is received while the app is foregrounded. */ 121 notificationListener.current = Notifications.addNotificationReceivedListener(notification => { 122 setNotification(notification); 123 }); 124 /* @end */ 125 126 /* @info This listener is fired whenever a user taps on or interacts with a notification (works when an app is foregrounded, backgrounded, or killed). */ 127 responseListener.current = Notifications.addNotificationResponseReceivedListener(response => { 128 console.log(response); 129 }); 130 /* @end */ 131 132 return () => { 133 Notifications.removeNotificationSubscription(notificationListener.current); 134 Notifications.removeNotificationSubscription(responseListener.current); 135 }; 136 }, []); 137 138 return ( 139 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'space-around' }}> 140 <Text>Your expo push token: {expoPushToken}</Text> 141 <View style={{ alignItems: 'center', justifyContent: 'center' }}> 142 <Text>Title: {notification && notification.request.content.title} </Text> 143 <Text>Body: {notification && notification.request.content.body}</Text> 144 <Text>Data: {notification && JSON.stringify(notification.request.content.data)}</Text> 145 </View> 146 <Button 147 title="Press to Send Notification" 148 onPress={async () => { 149 await sendPushNotification(expoPushToken); 150 }} 151 /> 152 </View> 153 ); 154} 155``` 156 157</Step> 158 159<Step label="3"> 160 161## Test using Expo Go and push notifications tool 162 163> This step allows testing the push notifications when developing your project using Expo Go. If you are using EAS or [development builds](/develop/development-builds/introduction/), you can skip this step and move on to the next one to configure credentials for Android and iOS. 164 165To test the example from the previous step, you can use Expo Go to open the project and the [Expo push notifications tool](https://expo.dev/notifications) to send a notification to your device. 166 167<ImageSpotlight 168 alt="Expo push notifications tool overview." 169 src="/static/images/notifications/push-notifications-tool-overview.jpg" 170 style={{ maxWidth: 1200 }} 171/> 172 173Make sure that the development server for your project is running. Then, open the project in the Expo Go app and after the `ExpoPushToken` is generated, enter the value in the Expo push notifications tool with other details (for example, a message title and body) and click on the **Send a Notification** button. 174 175After 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. 176 177<ImageSpotlight 178 alt="An Android device receiving a push notification." 179 src="/static/images/notifications/notification-on-android.jpg" 180 style={{ maxWidth: 360 }} 181/> 182 183</Step> 184 185<Step label="4"> 186 187## Get Credentials for development builds 188 189For Android and iOS, there are different requirements to set up your credentials. 190 191### Android 192 193For 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 (unless you are testing your project in Expo Go). 194 195> **warning** FCM is not currently available for `expo-notifications` on iOS. 196 197#### Setting up FCM 198 1991. To create a Firebase project, go to the [Firebase console](https://console.firebase.google.com/) and click on **Add project**. 200 2012. 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.** 202 2033. After registering the app, download the **google-services.json** file and place it in your project's root directory. 204 205 > 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). 206 2074. 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: 208 209 ```json app.json 210 { 211 "android": { 212 "googleServicesFile": "./google-services.json" 213 } 214 } 215 ``` 216 2175. 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: 218 219 ```json google-services.json 220 { 221 "client": [ 222 { 223 "api_key": [ 224 { 225 "current_key" "<your Google Cloud Platform API key>", 226 } 227 ] 228 } 229 ] 230 } 231 ``` 232 2336. 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**. 234 2357. 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**. 236 237 > 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**. 238 239Now you can re-build the development build using the `eas build` command. At this point, if you need to create a development build, see [creating development builds for a device](/develop/development-builds/create-a-build/#create-a-development-build-for-the-device). 240 241#### Upload server credentials 242 243For 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. 244 2451. In the Firebase console, next to **Project overview**, click gear icon to open **Project settings**. 246 2472. Click on the **Cloud Messaging** tab in the Settings pane. 248 2493. Copy the token listed next to the **Server key**. 250 251 > 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. 252 253 <ImageSpotlight 254 alt="Getting the server key from Firebase console's Cloud messaging tab." 255 src="/static/images/notifications/server-key-from-fcm.jpg" 256 style={{ maxWidth: 760 }} 257 /> 258 2594. 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`. 260 261 > For Legacy Application Identifiers, run `expo push:android:upload --api-key your-token-here`, replacing `your-token-here` with the string you just copied. We'll store your token securely on our servers, where it will only be accessed when you send a push notification. 262 2635. Under **Service Credentials** > **FCM Server Key**, click **Add a FCM Server Key** > **Google Cloud Messaging Token** and add the **Server key** from **step 3**. 264 265 > **warning** Having Service Credentials in both Legacy and non-legacy Application Identifiers can prevent push notifications from working on Android devices. If you have a Legacy Application Identifier, you should remove all of its Service Credentials. 266 267### iOS 268 269> **warning** A paid Apple Developer Account is required to generate credentials. 270 271For 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. 272 273If 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: 274 275- Setup Push Notifications for your project 276- Generating a new Apple Push Notifications service key 277 278<br /> 279 280> If you are not using EAS Build, you will need to run `eas credentials` manually. 281 282### Test using the push notifications tool 283 284After creating and installing the development build, you can use Expo's push notifications tool to send a test notification to your device. 285 286</Step> 287 288## Next 289 290<BoxLink 291 title="Send notifications using Expo's Push API" 292 description="Learn how to set your back-end using Expo's Push API, implementation practices, common errors and security best practices." 293 href="/push-notifications/sending-notifications" 294/> 295