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.jsonfile and place it in your project’s root directory.
[!IMPORTANT] The
google-services.jsonfile must be in the root directory of your project, at the same level aspackage.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:
EXPO_PUBLIC_PROJECT_ID=your_expo_project_idYou can find your Expo project ID in:
- Your Expo dashboard at expo.dev
- Or in
app.jsonunderextra.eas.projectId
[!IMPORTANT] The
EXPO_PUBLIC_PROJECT_IDis 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:
{
"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 withexpo 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:
- Create a new collection in your Appwrite database (e.g., “expoPushTokens”)
- Add a
tokenattribute (Type: String, Required: Yes) - Set permissions: Create and Delete for Users
- Update your
config/appwrite.jswith the collection ID:
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 androidOr 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:
- Make sure
google-services.jsonis in your project’s root directory - Verify
app.jsonincludes:"googleServicesFile": "./google-services.json"under theandroidsection - Create a new build after making these changes (the configuration is embedded during build time)
eas build --profile preview --platform androidNo Push Token Generated
If expoPushToken is null or undefined:
Check:
EXPO_PUBLIC_PROJECT_IDis set in your.envfile- You’re testing on a physical device (not an emulator)
- You’ve granted notification permissions when prompted
- 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:
- Appwrite is configured in
config/appwrite.js - The collection exists in your Appwrite database
- The collection has a
tokenattribute of type String - Collection permissions allow Create for Users
- Check the console logs for any Appwrite errors
Push Notifications Not Received
If notifications aren’t being delivered:
Check:
- The device has an active internet connection
- Notifications are enabled in device settings
- The app is not in the foreground (notifications only appear in background/killed state)
- The FCM credentials are correctly uploaded to EAS
- The push token is valid and not expired
Common Configuration Checklist
Before building, verify all of these are complete:
-
google-services.jsonfile in project root -
EXPO_PUBLIC_PROJECT_IDin.envfile -
googleServicesFileconfigured inapp.json - Firebase service key uploaded to EAS (
eas credentials) - Appwrite collection created with
tokenstring attribute - Collection permissions set correctly
-
config/appwrite.jshas correct collection ID - Created a new native build after configuration changes