15
votes

I am using Firebase push notifications in my Android App. I can send correctly notification with custom icon, but I have not managed to play my custom sound. I always get the default sound of my device.

{
    "registration_ids": "myToken",
    "notification": {
        "body": "my body",
        "title": "my title",
        "icon": "ic_notification",
        "sound": "mysound.mp3" // I tried "mysound", "mysound.wav"...

    },
    "priority": "high"

}

The custom sound is located in /res/raw

I have been able to play my custom sound with onMessageReceived and Firebase data message but not with Firebase notification message.

My android device is Xiaomi Mi A1 and Oreo 8.1., also tried with Xiaomi Mi A2 with same result.

I tried with php and curl, with node.js... always same problem, I get my default sound.

UPDATE

With this code for node.js does not work either:

var registrationToken = 'xxxxxx';

var message = {

    notification: {
      title: 'my title',
      body: 'my body',
    },
    android: {
      ttl: 3600 * 1000,
      notification: {
        color: '#ff0000',
        sound: 'mysound.mp3'
      }
    }, 
    token: registrationToken

};
7
Please refer to this documentation when structuring your message payload. In my experience, the only thing you should have in notification is { "body", "payload" }. Structure other settings in the platform specific sections (e.g. for sound, place the sound in message.android.notification.sound)James Poag

7 Answers

5
votes

Finally I found the solution. For Android 8.0 and higher it's necessary to create a notification channel in your App:

NotificationChannel channel = new NotificationChannel('my_id', name, importance);

(more info: https://developer.android.com/training/notify-user/channels#java)

Then when you send the notification:

var registrationToken = 'xxxxxx';

var message = {

    notification: {
      title: 'my title',
      body: 'my body',
    },
    android: {
      ttl: 3600 * 1000,
      notification: {
        color: '#ff0000',
        sound: 'mysound.mp3',
        channel_id: 'my_id' // important to get custom sound
      }
    }, 
    token: registrationToken

};
3
votes

From the documentation, include the sound in notification object under android object. Give name of the sound file in sound value. The sound files must reside in /res/raw/ . Below is a Node.js example:-

  var message = {
  notification: {
    title: 'sample title',
    body: 'Hello, its Tuesday.',
  },
  android: {
    ttl: 3600 * 1000,
    notification: {
      icon: 'my_icon',
      color: '#f45342',
      sound: 'filename.mp3',
    },
  },
  apns: {
    payload: {
      aps: {
        badge: 42,
      },
    },
  },
  topic: 'industry-tech'
};
3
votes

I was also looking for the solution to custom sound for firebase notification in the android, And I have solved this problem through Notification Channel.

I have created one notification channel with custom sound, that sound plays after receiving notification in the application background state.

You can refer following links of the notification channel.

https://medium.com/exploring-android/exploring-android-o-notification-channels-94cd274f604c

https://developer.android.com/training/notify-user/channels

You need to put your mp3 file at /res/raw/ path.

Please find the code.

NotificationManager notificationManager = (NotificationManager) getActivity().getSystemService(NotificationManager.class); // If you are writting code in fragment

OR

NotificationManager notificationManager = (NotificationManager) getSystemService(NotificationManager.class); // If you are writting code in Activity

createNotificationChannel function

private void createNotificationChannel() { 
 Uri sound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/" + R.raw.sample); //Here is FILE_NAME is the name of file that you want to play 
// Create the NotificationChannel, but only on API 26+ because 
// the NotificationChannel class is new and not in the support library if 
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 
 { 
    CharSequence name = "mychannel"; 
    String description = "testing"; 
    int importance = NotificationManager.IMPORTANCE_DEFAULT; 
    AudioAttributes audioAttributes = new AudioAttributes.Builder() 
     .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) 
     .setUsage(AudioAttributes.USAGE_ALARM) 
     .build(); 
   NotificationChannel channel = new NotificationChannel("cnid", name, importance); 
   channel.setDescription(description); 
   channel.enableLights(true); channel.enableVibration(true); 
   channel.setSound(sound, audioAttributes); 
   notificationManager.createNotificationChannel(channel); 
  } 
};

createNotificationChannel(); 

To achieve this you need to pass android_channel_id property in the firebase notification request object.

{
 "notification": {
 "body": "this is testing notification",
 "title": "My App",
 "android_channel_id": "cnid"
 },
 "to": "token"
}

Note - If you create a notification channel once then you can't change the sound. You have to create a new notification channel with the new name with your desired sound.

0
votes

Try Enabling Sound From Firebase Console

For More Info Just Look at this answer

https://stackoverflow.com/a/44304089/9024123

may be this should be problem and also try removing '.mp3' in sound element and make it like

"sound":"mySound"
0
votes

i was also facing the same issue. I always got the default sound but i fixed it as follows . I am using FCM-push (node module) https://www.npmjs.com/package/fcm-push

var message = {  
to : device_token,
collapse_key : '<insert-collapse-key>',
// data : {
//     '<random-data-key1>' : '<random-data-value1>',
//     '<random-data-key2>' : '<random-data-value2>'
// },
notification : {
    title : 'Title ',
    body : 'some Body',
    sound : 'notification' // my .ogg file in /res/raw
},
android: {
sound: 'notification' // my .ogg file name in /res/raw
}
};

I have not tried it with mp3 or wav and in your question it seems you have not tried with .ogg file ( though i doubt if it has anything to do with audio format but you can try)

0
votes

Maybe this helps : In my case i tried with the above approach and it did not worked, whenever i was checking in the onMessageReceived (for debug purpose) the channel id

Log.e(TAG, "Message Notification channel id: " + remoteMessage.getNotification().getChannelId()); 

i always got 'null'.

So reading the documentation from here https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support

I found out that i was using the wrong key for the channel id in the json.

Instead of 'channel_id' key try to use 'android_channel_id' key like this

"notification": {
        "body": "Body of Your Notification",
        "title": "Title of Your Notification",
        "android_channel_id": "channelId",
        "icon": "myIcon"
    }

If i use it like that it works as expected, custom sound (from res/raw) is played

PS: in my case i set my sound on the channelId when i created it

Good luck !

0
votes

One mistake I made when trying this was I didn't change the the channel id although I updated the Json and modified the code. My channel was always bound to the device sound. Just after I updated to a different channel id my code started working. Custom sound is now playing for both foreground and background

Following is the JSON which worked for me

{
"to" : "token"
,
"notification": {
    "title":"Server Notification Title",
    "body":"Notification Body",
    "sound":"sound.wav",
    "android_channel_id": "ch1"
},
"priority": "high"
}

The code

Uri soundUri = Uri.parse("android.resource://" + getApplicationContext().getPackageName() + "/" + R.raw.sound);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "ch1")
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(getString(R.string.app_name))
            .setContentText(remoteMessage.getNotification().getBody().toString())
            .setAutoCancel(true)
            .setSound(soundUri);

    NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        if(soundUri != null){
            // Changing Default mode of notification
            notificationBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
            // Creating an Audio Attribute
            AudioAttributes audioAttributes = new AudioAttributes.Builder()
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                    .setUsage(AudioAttributes.USAGE_ALARM)
                    .build();

            // Creating Channel
            NotificationChannel channel = new NotificationChannel("ch1","App Name",NotificationManager.IMPORTANCE_HIGH);
            channel.setSound(soundUri,audioAttributes);
            channel.enableLights(true); channel.enableVibration(true);
            mNotificationManager.createNotificationChannel(channel);
        }
    }
    mNotificationManager.notify(0, notificationBuilder.build());