React-native-push-notification: Android - No sound on notifications?

Created on 11 May 2020  路  47Comments  路  Source: zo0r/react-native-push-notification

Bug


Using {playSound: true, soundName: 'default'} doesn't work with localNotification. This affects both iOS and Android. Are there limitations on local notifications? I am able to turn on sound on Android if I configure the notification channel (from the OS settings) to use sound.

Environment info


Library version: 3.4.0

Steps To Reproduce

Most helpful comment

Check in ur Settings -> Notification -> Your App -> Sound, is a sound chosen?

All 47 comments

okay so this might sound a little stupid but it might be an issue for you too.

I was using the whole string
soundName: "android.resource://(your package name)/raw/my_sound"

instead of just using

soundName: "my_sound3" :D

You just have to use the exact name, not the whole string. I think someone should look at the comment which is written in the latest commit.

I'm using just 'default' (no custom sounds), yet the notification is set as no sound. What version are you using?

Probably related:
https://github.com/zo0r/react-native-push-notification/issues/1143
https://github.com/zo0r/react-native-push-notification/issues/1045

Oh. My default sound was playing fine. My version is
"react-native-push-notification": "^3.4.0",

"react-native": "0.62.2",

and I am testing on my Samsung Note 8.

I've tested on a Pixel 2 (Android 10) and Motorola G5 (Android 8.1), neither seem to work. It seems like the notification channel is created muted as default.

Can you show the code?

Sample Code:

import PushNotification from 'react-native-push-notification';


PushNotification.configure({

  // (optional) Called when Token is generated (iOS and Android)
  // NOT using push notifications from the server right now, this step is not done.
  onRegister: function(token) {
  },

  // (required) Called when a remote or local notification is opened or received
  onNotification: function(notification) {

    // required on iOS only
    if(Platform.OS == 'ios'){
      notification.finish(PushNotificationIOS.FetchResult.NewData);
    }
  },


  // ANDROID ONLY: GCM or FCM Sender ID (product_number) (optional - not required for local notifications, but is need to receive remote push notifications)
  //senderID: "YOUR GCM (OR FCM) SENDER ID",

  // IOS ONLY (optional): default: all - Permissions to register.
  permissions: {
    alert: true,
    badge: true,
    sound: true
  },

  // Should the initial notification be popped automatically
  // default: true
  popInitialNotification: true,

  /**
   * (optional) default: true
   * - Specified if permissions (ios) and token (android and ios) will requested or not,
   * - if not, you must call PushNotificationsHandler.requestPermissions() later
   * - if you are not using remote notification or do not have Firebase installed, use this:
   *     requestPermissions: Platform.OS === 'ios'
   */
  requestPermissions: Platform.OS === 'ios',
});



function showNotification(title, message, id, vibrate, sound, ongoing=false){
  PushNotification.localNotification({
    /* Android Only Properties */
    id: id,
    autoCancel: true,
    vibrate: vibrate,
    vibration: vibrate ? 300 : undefined,
    priority: "high",
    visibility: "public",
    importance: "high",
    ongoing: ongoing,

    /* iOS only properties */
    //alertAction: 'view',
    userInfo: {id: id}, // required for ios local notification

    /* iOS and Android properties */
    title: title,
    message: message, // (required)
    playSound: sound,
    soundName: sound ? 'default' : undefined,
    // number: number // silly library, iOS requires number, while android string...

  });
}


showNotification("Test", `Test.`, '0', true, true);

Check in ur Settings -> Notification -> Your App -> Sound, is a sound chosen?

Hum...
I think the problem comes from the management of sounds:

https://github.com/zo0r/react-native-push-notification/blob/master/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java#L363

Can you try to change in your node_modules, the file mentioned and change:

            if (!bundle.containsKey("playSound") || bundle.getBoolean("playSound")) {
                soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

                String soundName = bundle.getString("soundName");

                if (soundName != null) {
                    if (!"default".equalsIgnoreCase(soundName)) {

                        // sound name can be full filename, or just the resource name.
                        // So the strings 'my_sound.mp3' AND 'my_sound' are accepted
                        // The reason is to make the iOS and android javascript interfaces compatible

                        int resId;
                        if (context.getResources().getIdentifier(soundName, "raw", context.getPackageName()) != 0) {
                            resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
                        } else {
                            soundName = soundName.substring(0, soundName.lastIndexOf('.'));
                            resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
                        }

                        soundUri = Uri.parse("android.resource://" + context.getPackageName() + "/" + resId);

                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // API 26 and higher
                            channel_id = channel_id + "-" + soundName;
                        }
                    }
                }

                notification.setSound(soundUri);
            }

By:

            if (!bundle.containsKey("playSound") || bundle.getBoolean("playSound")) {
                soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

                String soundName = bundle.getString("soundName");

                if (soundName != null) {
                    if (!"default".equalsIgnoreCase(soundName)) {

                        // sound name can be full filename, or just the resource name.
                        // So the strings 'my_sound.mp3' AND 'my_sound' are accepted
                        // The reason is to make the iOS and android javascript interfaces compatible

                        int resId;
                        if (context.getResources().getIdentifier(soundName, "raw", context.getPackageName()) != 0) {
                            resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
                        } else {
                            soundName = soundName.substring(0, soundName.lastIndexOf('.'));
                            resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
                        }

                        soundUri = Uri.parse("android.resource://" + context.getPackageName() + "/" + resId);
                    }
                } else {
                    soundName = "default";
                }

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // API 26 and higher
                    channel_id = channel_id + "-" + soundName;
                }

                notification.setSound(soundUri);
            }

Hum...
I think the problem comes from the management of sounds:

https://github.com/zo0r/react-native-push-notification/blob/master/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java#L363

Can you try to change in your node_modules, the file mentioned and change:

            if (!bundle.containsKey("playSound") || bundle.getBoolean("playSound")) {
                soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

                String soundName = bundle.getString("soundName");

                if (soundName != null) {
                    if (!"default".equalsIgnoreCase(soundName)) {

                        // sound name can be full filename, or just the resource name.
                        // So the strings 'my_sound.mp3' AND 'my_sound' are accepted
                        // The reason is to make the iOS and android javascript interfaces compatible

                        int resId;
                        if (context.getResources().getIdentifier(soundName, "raw", context.getPackageName()) != 0) {
                            resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
                        } else {
                            soundName = soundName.substring(0, soundName.lastIndexOf('.'));
                            resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
                        }

                        soundUri = Uri.parse("android.resource://" + context.getPackageName() + "/" + resId);

                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // API 26 and higher
                            channel_id = channel_id + "-" + soundName;
                        }
                    }
                }

                notification.setSound(soundUri);
            }

By:

            if (!bundle.containsKey("playSound") || bundle.getBoolean("playSound")) {
                soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

                String soundName = bundle.getString("soundName");

                if (soundName != null) {
                    if (!"default".equalsIgnoreCase(soundName)) {

                        // sound name can be full filename, or just the resource name.
                        // So the strings 'my_sound.mp3' AND 'my_sound' are accepted
                        // The reason is to make the iOS and android javascript interfaces compatible

                        int resId;
                        if (context.getResources().getIdentifier(soundName, "raw", context.getPackageName()) != 0) {
                            resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
                        } else {
                            soundName = soundName.substring(0, soundName.lastIndexOf('.'));
                            resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
                        }

                        soundUri = Uri.parse("android.resource://" + context.getPackageName() + "/" + resId);
                    }
                } else {
                    soundName = "default";
                }

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // API 26 and higher
                    channel_id = channel_id + "-" + soundName;
                }

                notification.setSound(soundUri);
            }

Changed the above, re-sync gradle, did gradlew clean and react-native run-android but it didn't work for me. The Sound selected by default is still "None" instead of the default sound.

Edit: Mine is remote notification though

@Gabsys
This fix is not for remote notification since remote notification use a default channel which is not impacted by this change, will make the change for both ASAP.

Check in ur Settings -> Notification -> Your App -> Sound, is a sound chosen?

Sound is available, but no chosen ("no sound" / "none"). Of course I could choose a sound there, and then it works, but it should be turned on by default.

@Dallas62 what about iOS local notifications? They seem muted as well,

Check in ur Settings -> Notification -> Your App -> Sound, is a sound chosen?

Sound is available, but no chosen ("no sound" / "none"). Of course I could choose a sound there, and then it works, but it should be turned on by default.

Yes, I face the same issue. I believe @Dallas62 is fixing it now

Hi,
I put some changes in dev branch, can you test them ?

yarn add zo0r/react-native-push-notification#dev

OR

npm install zo0r/react-native-push-notification#dev

You probably need to reinstall the application, but if this is already released, you can also set:

<meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="rn-push-notification-channel-id-default-4-300" />

in AndroidManifest

You probably need to reinstall the application, but if this is already released, you can also set:

<meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="rn-push-notification-channel-id-default-4-300" />

in AndroidManifest

Hi @Dallas62 ,
Local Push Notifications is working properly with Custom Sound, but when I send a notification from Firebase (FCM) with custom sound, it's not working properly. (Default Notification Sound is playing instead)

My bet, It could be something to do with the payload sent through the FCM as well.

The Payload which I'm trying to send

const payload = {
notification: {
alert: "You have a notification",
title: "This is a Notification",
body: "This is the body of the notification message.",
sound: "sound.mp3",
soundName: "sound.mp3",
sticky: "true",
image:
"https://www.gstatic.com/devrel->devsite/prod/v84899ba5ac366dd19b845bb4579ea9262ac5ac73d5db61a8fa440a5f2fc65a26/fi>rebase/images/lockup.png",
},
data: {},
};`

On Foreground

When I console notification of onNotification(notification)

>

color: null
data: {}
finish: 茠 finish()
foreground: true
id: "-1628629521"
message: "This is the body of the notification message."
sound: "sound"
title: "This is a Notification"
userInteraction: false
__proto__: Object

As you see the sound:"sound.mp3" is received as "sound", Is that could be an issue?

I also tried installing the dev & set the above lines in AndroidManifest, No result.

Hi @anishsrinivasan
This is not the same issue, but I think this is due to the Channel of Android which is configured for a specific sound.
Since the library as a poor support of channels, in the current state of the library, I don't have a workaround...

You probably need to reinstall the application, but if this is already released, you can also set:

<meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="rn-push-notification-channel-id-default-4-300" />

in AndroidManifest

Do we need this even if we only use local notifications? I will try to test it once I get time.

This is not needed for local notification, only remote.
But if you can try this:
https://github.com/zo0r/react-native-push-notification/issues/1432#issuecomment-627774916

@Dallas62 The #dev version solves the problem for local notifications with default sound for me. Thank you very much! When can we expect a new version with this fix?
Tested on Samsung Galaxy M30s, Android 9 => works

Hi @hubermat
Thanks for the feedback,
I will check this in the next tow days

Sounds seem to be fixed in the latest release, but now they somehow defeat the volume settings of the OS.

I've got my notification volume silenced and the notifications for this app come out at full volume anyway. Some of our users reported it's really soft for them, despite having their phones set at full volume.

Hi @wbercx
Is it for remote notification ?
If yes, set the default channel of firebase in the AndroidManifest:

<meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="rn-push-notification-channel-id-default-4-300" />

But it seems like there is an issue with DND which is ignored, I'm looking into it.

Is it for remote notification ?

@Dallas62 Nah, local notifications.

It appears to be using the Alarm volume, rather than Notification/Ringtone volumes. If I go to the Clock app and I change the alarm volume in there, that affects the next notification that is displayed.

So far this seems to work, but I haven't done thorough testing yet:

diff AudioAttributes audioAttributes = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) - .setUsage(AudioAttributes.USAGE_ALARM) + .setUsage(AudioAttributes.USAGE_NOTIFICATION) .build();

@wbercx This change works and solve the DND issue ! 馃殌
I will check 2 others issues and release a fix ASAP.
One problem of this change is it's not applied on installed application, a solution is to change the default vibration (if any like 300 => 301) to force create a new channel, but this workaround is :vomiting_face:

@Dallas62 Nice!

That's one other thing I noticed. It creates two channels now - one with sound and one without - but it uses the same name for both. While some of our users tried to work out why it was so quiet, they were wondering why the same entry appeared twice in the Settings app.

Could we dynamically add - silent at the end of the silent channel's name, or is there a way to address this ourselves in the AndroidManifest?

@wbercx I can implement a solution to select a name / description based on the ID, and fallback to the default (like the actual behaviour).
But this is not the right way to manage this... Since I don't have time to refactor channel management for now, it's probably the best workaround..

By changing:

public String getChannelName()
public String getChannelDescription()

To

public String getChannelName(String channel_id)
public String getChannelDescription(String channel_id)

in RNPushNotificationConfig.java

I will release a fix for the current issue, and push on dev branch a way to manage different channel name based on channel.

The version 3.5.2 has been released.
You can test the change for Channel Name on zo0r/react-native-push-notification#dev:

yarn add zo0r/react-native-push-notification#dev
OR
npm install zo0r/react-native-push-notification#dev

I will test it later today, AndroidManifest should be updated like this:

        <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_name"
                android:value="DEFAULT NOTIFICATION CHANNEL NAME"/>
        <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_description"
                    android:value="DEFAULT NOTIFICATION CHANNEL DESCRIPTION"/>

        <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_name.CHANNEL_ID"
                android:value="YOUR CHANNEL_ID NOTIFICATION CHANNEL NAME"/>
        <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_description.CHANNEL_ID"
                    android:value="YOUR CHANNEL_ID NOTIFICATION CHANNEL DESCRIPTION"/>

Default channels id:

  • rn-push-notification-channel-id-default-4-300
  • rn-push-notification-channel-id-4-300

@Dallas62 You're a legend, thanks for the quick turnaround on everything! Much appreciated!

Just to be sure, we need to use the channels rn-push-notification-channel-id-default-4-300 and rn-push-notification-channel-id-4-300 in our manifest in order to customize the notification description, or can we use our own ids?

Hi @cristianoccazinsp
You have to use the ID of the library:

  • rn-push-notification-channel-id-default-4-300
  • rn-push-notification-channel-id-4-300

Since ID are generated based on local notification parameters (馃ぎ) you can use "custom" channel id if they follow this pattern:
rn-push-notification-channel-id(-soundname, default if playSound "-default")-(importance: default "4")-(vibration, default "300")

Thanks. As long as it is documented, I don't think it is so bad. I haven't been able to test the updates yet, but I will let you know how it goes once I do it.

Apparently even on 3.5.2 after a full reinstall some users are not getting sound when they receive a notification. I cannot reproduce it myself though...

@Dallas62 just tried this for local notifications, and it seems to be working fine!

I didn't have to change the manifest at all, can you clarify if that's required, or just optional if we want custom names for each notification channel?

My current manifest:

 <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_name"
                android:value="DEFAULT NOTIFICATION CHANNEL NAME"/>
        <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_description"
                    android:value="DEFAULT NOTIFICATION CHANNEL DESCRIPTION"/>

Hi @cristianoccazinsp
If you use the default entry you mentioned in AndroidManifest, all channels will have the same name.
On dev branch, take a look at the Readme I put more information on channels and coming changes

Hi @d0xi5
This repository in not the iOS one, look at iOS repository.
Regards,

Tried it on Android and Im getting no sound. I have my file in raw directory, and
soundName: Platform.OS === 'android' ? 'android.resource://com.appbundle/raw/ding' : 'ding.wav'

Im receiving the notification but its not vibrating nor making any sound. I tried with 'default' and nothing. I have also checked the permissions under the app for sound and they are fine.
Any guess?

I have added on manifiest the following:

`

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>

<uses-permission android:name="android.permission.VIBRATE" />

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="rn-push-notification-channel-id-ding-4-300" />

    <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_name"
        android:value="Sound channel"/>
    <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_description"
        android:value="A sound channel"/>

    <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_name.CHANNEL_ID"
        android:value="rn-push-notification-channel-id-ding-4-300"/>
    <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_description.CHANNEL_ID"
        android:value="A sound channel"/>

    <!-- Change the value to true to enable pop-up for in foreground (remote-only, for local use ignoreInForeground) -->
    <meta-data  android:name="com.dieam.reactnativepushnotification.notification_foreground"
        android:value="false"/>
    <!-- Change the resource name to your App's accent color - or any other color you want -->
    <meta-data  android:name="com.dieam.reactnativepushnotification.notification_color"
        android:resource="@color/white"/> <!-- or @android:color/{name} to use a standard color -->

    <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
    <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
    <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
        </intent-filter>
    </receiver>

    <service
        android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

`

And on NotifService.js

`

PushNotification.createChannel(
  {
    channelId: 'rn-push-notification-channel-id-ding-4-300', // (required)
    channelName: `Sound channel`, // (required)
    channelDescription: 'A sound channel', // (optional) default: undefined.
    soundName:
      Platform.OS === 'android'
        ? 'android.resource://com.ascendapp/raw/ding'
        : 'ding.wav', // (optional) See `soundName` parameter of `localNotification` function
    importance: 4, // (optional) default: 4. Int value of the Android notification importance
    vibrate: true // (optional) default: true. Creates the default vibration patten if true.
  },
  created =>
    console.log(`createChannel 'sound-channel-id' returned '${created}'`) // (optional) callback returns whether the channel was created, false means it already existed.
)

scheduleNotif(soundName, time, title, subtitle) {
this.lastId++

PushNotification.localNotificationSchedule({
  date: new Date(Date.now() + time * 1000),

  /* Android Only Properties */
  channelId: 'rn-push-notification-channel-id-ding-4-300',
  autoCancel: true, 
  bigText: title, 
  vibrate: true, 
  vibration: 300,  
  invokeApp: false,  

  when: null, 
  usesChronometer: false, 
  timeoutAfter: null, 

  /* iOS only properties */
  alertAction: 'view',  
  category: '',  

  /* iOS and Android properties */
  id: this.lastId,  
  title: title,  
  message: subtitle,  
  userInfo: { sceen: 'home' },
  playSound: true, 
  soundName:
    Platform.OS === 'android'
      ? 'android.resource://com.ascendapp/raw/ding'
      : 'ding.wav' 
})

}
`

Am I missing something?

Hi @d0xi5

Did you try to make a fresh install of the application or change the notification id ?
If you made some test with the same device, the channel might be created and will not be updated (Android Policy).
Also did you try the example project which provide an example with sounds ?

@Dallas62 I have tried both things and no luck. Just the notification but without sound and without vibration. Phone is on sound mode.

I couldn't try example app, I had some errors on Android Studio.

Found the issue, I was doing

let notif = new NotifService()

Inside the component (hooks), and the channel was being created a lot of times. I passed that code outside of it
and the channel is being created only once, and sound is working.

Thank you for you quick reply @Dallas62

sound

Check in ur Settings -> Notification -> Your App -> Sound, is a sound chosen?

Sound is available, but no chosen ("no sound" / "none"). Of course I could choose a sound there, and then it works, but it should be turned on by default.

Yes, I face the same issue. I believe @Dallas62 is fixing it now

Hi @Dallas62,

How to make turn on sound by default? Did we fixed it on new version?

Thank you

how can we play a custom sound in remote notification ?
i have tried with many solution but it doesn't work on remote notification while custom sound work on local notification,

is there any solution ?

Thanks in advance

First, giving 4 to the importance parameter.
The problem will be solved when you remove the playSound and soundName parameters and send the default value.

I have a similar problem, If I create a channel and set the soundName as "default" or just remove it, it will always play the default sound, even when I schedule a notification with another custom sound.
I can however play the custom sound when I add it in the Create Channel Object, I need to play different custom sounds for the scheduled notifications on the same channel? is this possible?

on the latest 7.2.3 version.

Hi @UxmanKaxmi
Sounds are defined on channels, you can't override or change the sound of a channel.
Please refer to the Android documentation about channels.
Regards

Was this page helpful?
0 / 5 - 0 ratings