Enable push notifications in an Expo app (Android)
This guide walks you through enabling push notifications in your Expo app on Android using the Acoustic Connect SDK and Firebase Cloud Messaging (FCM).
Language: TypeScript and JavaScript
Availability: Pro, Premium, and Ultimate
Scope: Test setup — building, running on a connected device or emulator, and verifying push delivery. For bare React Native, see Enable push notifications in a React Native app (Android). For production setup, see Move your React Native integration to production.
Sample app: See our GitHub repository for a reference implementation to compare your configuration against.
Prerequisites
- A Firebase project with your Android app registered. If you do not have one, create it at console.firebase.google.com.
- Connect app key that supports push notifications. Push requires an app key from a Mobile app integration created after April 2026. If your integration is older, ask your Connect administrator to create a new one and provide you with the new app key. For instructions, see Connect mobile apps in the Connect user guide.
- Connect React Native SDK version 19.0.9 integrated in your Expo project. If you have not yet integrated the SDK, follow Integrate the Connect SDK into an Expo app first.
Overview
- Get your Firebase service account key.
- Share your Firebase credentials with your Connect administrator.
- Add google-services.json to your Expo project.
- Configure push notifications in your development project.
- Add a notification icon.
- Add code to request notification permission from your users.
Step 1: Generate a Firebase service account key
- In the Firebase console, open your project.
- Go to Project settings > Service accounts.
- Click Generate new private key and confirm. Firebase downloads a
.jsonfile to your computer.
Connect uses this file to authenticate with FCM on your behalf when sending push notifications. For more information, see Initialize the SDK in non-Google environments in the Firebase documentation.
Step 2: Share Firebase credentials with your Connect administrator
Share the following with your Connect administrator so they can enable push on your Mobile app integration.
| Credential | Where to find it |
|---|---|
| Service account key | The .json file downloaded in Step 1 |
| Package name | app.json → expo.android.package |
See Connect mobile apps in the Connect user guide.
Step 3: Add Firebase to your Expo project
- In the Firebase console, go to Project settings > General.
- Under Your apps, select your Android app. Confirm it's registered with the same package name as
expo.android.packageinapp.json— FCM matches its client by package name, and a mismatch fails the build later at:app:processDebugGoogleServices. - Download google-services.json and place it in the root of your project (alongside
app.json). - Reference the file in
app.json:
{
"expo": {
"android": {
"googleServicesFile": "./google-services.json"
}
}
}
NoteYou don't need to apply the Google Services Gradle plugin or add the Firebase Messaging dependency yourself — Expo and the Connect SDK handle both automatically. For manual mode, where your app manages its own
FirebaseMessagingServiceand forwards messages to the SDK, contact Acoustic support — manual mode is not covered in this guide.
Step 4: Configure push notifications in your development project
-
Open ConnectConfig.json in the root of your project and add the following keys inside the
Connectobject:{ "Connect": { "AppKey": "YOUR_PUSH_ENABLED_APP_KEY", "PostMessageUrl": "YOUR_COLLECTOR_URL", "PushEnabled": true, "AndroidNotificationIconResName": "ic_notification" } }Key Value PushEnabledtrue— enables push support in the SDK.AndroidNotificationIconResNameThe name of your notification icon drawable resource, without the file extension or folder path. -
Run
npx expo prebuildto apply your configuration to the native project.npx expo prebuild -
Validate your configuration:
npx acoustic-connect doctor --require-pushWhat the Doctor does
--require-pushtreats the push-required values —AppKey, the collector URLs, andAndroidNotificationIconResName— as hard failures rather than warnings, so a typo or leftover placeholder is caught here instead of failing later in Gradle or on-device. It's safe to re-run any time you change ConnectConfig.json.
Step 5: Add a notification icon
Android requires a small monochrome icon for the notification drawer. The system applies a color tint at display time; design it as a white icon on a transparent background.
Because expo prebuild regenerates the android/ directory and it is not committed to your repository, repeat these steps after every prebuild:
- In Android Studio, right-click
android/app/src/main/resand select New > Image Asset. - Set Icon type to Notification Icons, enter
ic_notificationas the name, and import your source image. - Click Next > Finish. Android Studio generates the icon at the required densities under
res/drawable-*.
The name you give the icon must match AndroidNotificationIconResName in ConnectConfig.json exactly.
WarningIf
AndroidNotificationIconResNameis set but the drawable is missing from your project, the SDK falls back to the app launcher icon. The launcher icon is typically not optimized for the notification drawer and may appear incorrectly tinted.
Step 6: Request notification permission
On Android 13 (API 33) and later, your app must request notification permission at runtime. Call pushRequestPermission() at an appropriate moment in your app's UX — for example, after an onboarding screen that explains the value of notifications.
import AcousticConnectRN from 'react-native-acoustic-connect'
const result = await AcousticConnectRN.pushRequestPermission()
if (result.granted) {
console.log('Notification permission granted')
} else {
console.log('Notification permission denied:', result.error)
}pushRequestPermission() presents the system permission dialog on Android 13+ when the state is undetermined. On Android 12 and earlier, notifications are granted by default and the method resolves immediately with { granted: true }. It always resolves and never rejects.
You can also check the current permission state without prompting:
const granted = await AcousticConnectRN.pushGetPermissionState()
// true = granted, false = denied, null = not yet determinedTesting
Testing push notifications requires a physical device or an emulator with Google Play Services — FCM does not work on AOSP emulators.
-
Connect your device via USB and build with:
npx expo run:android -
Grant notification permission when prompted. A new mobile contact is created in Connect and your device becomes eligible to receive pushes.
-
Coordinate with your marketing team to send a test push to your device, or do it yourself — see Test your push notification setup.
-
Verify the notification appears, and push signals appear in the contact's activity feed in Connect.
Enabling SDK debug logging
Inspect Logcat in Android Studio using a filter like package:<your.app.package> | tag:AndroidRuntime | tag:Tealeaf | tag:EOCore | tag:Connect. When reporting an issue to support, attach your Logcat output.
Message structure
After you complete the setup, your marketing team creates message content in Message composer in Connect. The following elements make up a push message, and each has its own source and constraints.
- Notification icon — shown alongside every notification. Unlike the other elements below, it's not set in Message composer; it's always taken from the development project. See Add a notification icon above. If the drawable is missing, notifications fall back to the app launcher icon instead of your branding.
- Title and body — authored per message; no SDK-imposed character limit, though Android may truncate long text in the notification shade depending on device and OS version.
- Thumbnail image — shown in the collapsed notification, useful for branding. Accepted formats: .jpg, .jpeg, .png. Minimum dimensions: 64 × 64 px. Maximum size: 5 MB.
- Expandable content — additional text or a full image shown when the user expands the notification. This is rich media delivered through FCM's data payload and is fully customizable per message, independent of the notification icon.
- Actionable notifications — a built-in action that fires when the user taps the notification: open the app, call a number, or open a URL.
Troubleshooting
Push notifications not received
- Confirm
PushEnabledistruein ConnectConfig.json and that you re-rannpx expo prebuildafter the change. - Confirm google-services.json exists at the path set in
app.json→expo.android.googleServicesFileand matches your Firebase project and package name. - On API 33+, confirm the user granted notification permission. Call
pushGetPermissionState()to check. - Test on a physical device or an emulator with Google Play Services — FCM does not work on AOSP emulators.
Push signals not appearing in Connect
- Confirm
AppKeyandPostMessageUrlin ConnectConfig.json match your Mobile app integration in Connect. - Confirm your Connect administrator has uploaded your Firebase service account key to the Mobile app integration.
Notification icon not showing correctly
- Confirm
AndroidNotificationIconResNamein ConnectConfig.json matches the drawable resource name exactly (no extension, no folder path). - Confirm the icon is a white monochrome design on a transparent background. Colorful icons are flattened to grey by the Android system.
- Confirm the drawable exists under
res/drawable-*after your most recent prebuild. Sinceexpo prebuildregeneratesandroid/, re-run the Image Asset step in Step 5 if you generated the icon before your last prebuild.
Config changes don't take effect
ConnectConfig.json is baked in at build time, not read at runtime. Rebuild with npx expo prebuild --clean — a Metro reload is not enough.
Next step: Identify app users
Push setup is now complete. To make the most of push notifications, identify the people receiving them — see User identification signals in a React Native app.
