Firebase Custom Notification Sound
This page covers how to make a push notification play a custom sound when you send it directly through the Firebase Cloud Messaging HTTP v1 API
This is the FCM-specific half of Notification Sound. Before sending anything below, your app must already have the sound file uploaded via the Dashboard — see Uploading the Sound File on the OS Notification Sound page. FCM only tells the OS which uploaded sound to play, it does not deliver the sound file itself.
If you send pushes through the OneSignal Dashboard instead of calling FCM directly, use Custom Notification Sound via OneSignal instead — this page is for apps/backends that call the FCM API directly.
Endpoint
POST https://fcm.googleapis.com/v1/projects/{project_id}/messages:send
Authorization: Bearer {OAuth2_access_token}
Content-Type: application/jsonHow Sound Works Per Platform
iOS: the native APNs payload has a real
soundfield (apns.payload.aps.sound). Set it to the sound's filename with extension (e.g.custom_notify.wav/.caf), matching what you uploaded for iOS. Use"default"for the system sound.Android: FCM has no native sound field. The sound actually played is whichever sound is attached to the Notification Channel the notification is delivered on — so for Android, "setting the sound" really means routing the notification to the right channel, either via the native
android.notification.channel_idfield, or by sending the sound name throughdataand having your app code build the notification on that channel itself. Both approaches are shown below.
Payload Structure
{
"message": {
"token": "eH3kP9vQxT2:APA91bF7sN4dR8mLzYcW1oJpX6qKvA0uZtG3nBhMwEsRfCiVdT5jHkOlPmNq",
"android": {
"priority": "high",
"notification": {
"channel_id": "high" // Android: routes to a channel that already has the custom sound attached — see "Android: Channel-Based Sound" below
}
},
"apns": {
"headers": {
"apns-priority": "10"
},
"payload": {
"aps": {
"alert": {
"title": "Your order has shipped",
"body": "Order #48213 is on its way and will arrive by Thursday."
},
"sound": "custom_notify.wav", // iOS: native APNs sound, played by the OS when the app is backgrounded/killed
"mutable-content": 1
}
}
},
"data": {
"title": "Your order has shipped",
"body": "Order #48213 is on its way and will arrive by Thursday.",
"sound": "custom_notify", // Android: sound key your app code reads if you're building the notification yourself instead of using android.notification.channel_id
"channel_id": "high"
}
}
}Field Reference
message (object, required)
Root wrapper for the entire notification request. FCM requires exactly one target field inside it — here it's token.
token
string
The FCM registration token of the target device. Identifies the single device/app instance to receive the message.
android.notification.channel_id — Channel-Based Sound (Recommended for Android)
channel_id
string
The ID of an Android Notification Channel that already exists on the device with your custom sound attached (created via NotificationManager.createNotificationChannel() in your Android app code). FCM applies this channel automatically — no app code needed to read it.
If the channel doesn't already exist on the device, Android falls back to a default channel and plays the default sound.
data.sound / data.channel_id — App-Handled Sound (Alternative for Android)
Use this instead of android.notification.channel_id only if your app already builds notifications manually in code (custom rendering, rich media, etc.) rather than relying on FCM's auto-displayed notification.
sound
string
Sound resource identifier your own app code reads to pick a sound or channel when constructing the notification. Not applied automatically by FCM/Android — your app must read data.sound itself.
channel_id
string
Target Android Notification Channel ID. Like sound, this sits in the custom data block, so it is not auto-applied — your app code must read this value and pass it explicitly (e.g. NotificationCompat.Builder(context, channelId)) when building the notification.
All
datavalues must be strings. FCM rejects numbers/booleans indata— send"1"/"true"instead.
apns.payload.aps.sound — iOS Sound
Native Apple Push payload (aps dictionary), passed through unmodified by FCM to APNs.
sound
string
Name of a custom sound file uploaded for the app (e.g. custom_notify.caf/.wav), matching what's uploaded per OS Notification Sound. Played natively by APNs when the app is backgrounded or killed. Use "default" for the system sound.
mutable-content
int (0/1)
When 1, allows a Notification Service Extension to intercept and modify the notification before display. Not required just for a custom sound — only needed if you're also modifying content (e.g. downloading media).
apns.headers.apns-priority
apns-priority
string
"10" = send immediately — required for a notification with a custom sound to actually play it; "5" delivers silently in the background with no sound/alert.
Sample cURL Request
Implementation Checklist
Frequently Asked Questions
Official Documentation References
FCM HTTP v1 API — Send Messages — overview of building and sending messages via the v1 API.
projects.messages.sendREST Reference — full request/response schema for themessages:sendendpoint.ApnsConfigReference — schema for theapnsblock (headers,payload).Apple: Generating a Remote Notification (
apspayload) — canonical spec foralert,sound,mutable-content, and otherapskeys.Create and Manage Notification Channels (Android) —
NotificationManager.createNotificationChannel()and channel importance/sound behavior.
Last updated