Skip to Content
ConfigurationExpo Push Notifications

Expo Push Notifications

This guide will walk you through setting up push notifications for your app using Expo Push Notification Service and Firebase Cloud Messaging.

Prerequisites

Before you begin, make sure you have:

  • An Expo account and project set up
  • A Firebase account
  • Your app’s package name (Android) or bundle ID (iOS)

1. Set Up Firebase Credentials

Follow the official Expo guide on setting up Firebase Cloud Messaging (FCM) credentials: Expo Push Notifications - FCM Credentials 

2. Add Firebase to Your App

  • Register your app in the Firebase Console.
  • Use your app’s package ID to set up the project.
  • Download the google-services.json file and place it in your project’s root directory.

[!IMPORTANT] The google-services.json file must be in the root directory of your project, at the same level as package.json.

3. Configure EAS (Expo Application Services)

  • Add the Firebase service key to EAS using the Expo CLI.

    eas credentials
  • Follow the prompts to upload the key.

4. Get Android Keystore SHA-1 Fingerprint

  • In the Expo dashboard, locate the Android keystore (requires a prior build).
  • Retrieve the SHA-1 fingerprint needed for Firebase setup.

5. Configure Environment Variables

Add your Expo project ID to the .env file:

.env
EXPO_PUBLIC_PROJECT_ID=your_expo_project_id

You can find your Expo project ID in:

  • Your Expo dashboard at expo.dev 
  • Or in app.json under extra.eas.projectId

[!IMPORTANT] The EXPO_PUBLIC_PROJECT_ID is required for push notifications to work properly. Without it, the app won’t be able to register for push notifications.

6. Update app.json

Add the Firebase configuration to your app.json file. This tells Expo where to find your google-services.json file:

app.json
{ "expo": { "android": { "package": "com.yourcompany.yourapp", "googleServicesFile": "./google-services.json" } } }

[!WARNING] After modifying app.json, you must create a new build for the changes to take effect. JavaScript-only changes can be updated with expo start, but native configuration changes require a rebuild.

7. Set Up Appwrite Collection for Push Tokens (Optional)

[!NOTE] This step is optional. Only complete this if you want to store push tokens in Appwrite for managing notifications across devices.

If you’re using Appwrite to store push tokens:

  1. Create a new collection in your Appwrite database (e.g., “expoPushTokens”)
  2. Add a token attribute (Type: String, Required: Yes)
  3. Set permissions: Create and Delete for Users
  4. Update your config/appwrite.js with the collection ID:
config/appwrite.js
const config = { // ... other config col: { expoPushTokens: "your_collection_id_here", }, }

8. Create a Development Build

For push notifications to work, a development build must be created using EAS Build:

eas build --profile development --platform android

Or for a preview build (APK):

eas build --profile preview --platform android

[!NOTE] Push notifications require a native build. They will not work in Expo Go. After creating the build, install the APK on your device and test the notifications.

9. Using Push Notifications in Your App

Once everything is configured, you can use the PushNotificationProvider to send notifications from your components:

import { usePushNotifications } from "../providers/PushNotificationProvider"; const { expoPushToken, sendPushNotification } = usePushNotifications(); <ButtonHorizontal title="Send Push Notification" onPress={async () => { const message = { to: expoPushToken, title: "Test Notification", body: "This is a test notification", }; try { await sendPushNotification(expoPushToken, message); Toast.show({ type: "success", text1: "Notification sent!" }); } catch (error) { Toast.show({ type: "error", text1: "Failed to send" }); } }} />

Troubleshooting

Error: “FirebaseApp is not initialized”

This error means the google-services.json file isn’t properly configured:

Solutions:

  1. Make sure google-services.json is in your project’s root directory
  2. Verify app.json includes: "googleServicesFile": "./google-services.json" under the android section
  3. Create a new build after making these changes (the configuration is embedded during build time)
eas build --profile preview --platform android

No Push Token Generated

If expoPushToken is null or undefined:

Check:

  1. EXPO_PUBLIC_PROJECT_ID is set in your .env file
  2. You’re testing on a physical device (not an emulator)
  3. You’ve granted notification permissions when prompted
  4. You’re using a development/preview build (not Expo Go)

Tokens Not Saving to Appwrite

If tokens aren’t being stored in your Appwrite database:

Verify:

  1. Appwrite is configured in config/appwrite.js
  2. The collection exists in your Appwrite database
  3. The collection has a token attribute of type String
  4. Collection permissions allow Create for Users
  5. Check the console logs for any Appwrite errors

Push Notifications Not Received

If notifications aren’t being delivered:

Check:

  1. The device has an active internet connection
  2. Notifications are enabled in device settings
  3. The app is not in the foreground (notifications only appear in background/killed state)
  4. The FCM credentials are correctly uploaded to EAS
  5. The push token is valid and not expired

Common Configuration Checklist

Before building, verify all of these are complete:

  • google-services.json file in project root
  • EXPO_PUBLIC_PROJECT_ID in .env file
  • googleServicesFile configured in app.json
  • Firebase service key uploaded to EAS (eas credentials)
  • Appwrite collection created with token string attribute
  • Collection permissions set correctly
  • config/appwrite.js has correct collection ID
  • Created a new native build after configuration changes