phonegap / phonegap-plugin-push

Register and receive push notifications
MIT License
1.94k stars 1.91k forks source link

No sound, no vibration, data.sound & data.vibrate fields not as documented #1147

Closed ppetree closed 7 years ago

ppetree commented 8 years ago

Expected Behaviour

Payloads are different per platform and doesn't follow documentation for payloads. Default sound to be played and vibration if those flags are set

Actual Behaviour

Payload is not per documentation:

No sound played, no vibration. Android fails to set badge

Reproduce Scenario (including but not limited to)

Sending using GCM to both platforms.

Steps to Reproduce

Platform and Version (eg. Android 5.0 or iOS 9.2.1)

iOS 9.3.3 on an iPad3, iPhone 4s, iPhone 5 Android 4.2.2 on a NextTab (latest version for that device)

Cordova CLI version and cordova platform version

CLI 5.4.1 for both Android and iOS

Plugin version

1.6.4 (latest version that works with XDK)

Sample Push Data Payload

Apple fields to GCM:

{"priority":"high","notification":{"body":"Life threatening emergency; Heart attack","title":"Medical Emergency","vibrate":true,"custom_field_1":46,"custom_field_2":"2","sound":"default"},"registration_ids":["m_zCoZhBNDE:blahblahblah","mvIqmUsmOYk:blahblahblah"]}

iOS Push Payload:

{"title":"Medical Emergency",
"sound":"default",
"additionalData":{"foreground":false,
                  "gcm.message_id":"0:1470426723672831%b7f1dca2b7f1dca2",
                  "gcm.notification.vibrate":"true",
                  "gcm.notification.custom_field_1":"44",
                  "coldstart":false,
                  "gcm.notification.custom_field_2":"2"},
"message":"Life threatening emergency; Heart attack"}

Android fields to GCM:

{"priority":"high","data":{"message":"Life threatening emergency; Heart attack","alert":"Medical Emergency","title":"Medical Emergency","category":"Medical Emergency","style":"inbox","vibrate":true,"sound":"default","custom_field_1":46,"custom_field_2":"2"},"registration_ids":["cW5Z_tJ7qo8:blahblahblah"]}

Android Push Payload:

{"message":"Life threatening emergency; Heart attack",
"additionalData":{"category":"Medical Emergency",
                  "custom_field_1":"44",
                  "collapse_key":"do_not_collapse",
                  "custom_field_2":"2",
                  "style":"inbox",
                  "coldstart":false,
                  "vibrate":"true",
                  "foreground":false},
"sound":"default",
"title":"Medical Emergency"}

Sample Code that illustrates the problem

  push.on('notification', function(data) {
      var info = [];
      var msgid;
      var vibrate;
      var sound;

      // data.message,
      // data.title,

      // these two are simply not true...
      // data.sound,
      // data.image,

      // data.count,
      push.setApplicationIconBadgeNumber(function() {
          console.log('icon badge set!');
        }, function() {
          console.log('icon badge failed!');
      }, getUnreads()+1);

      // data.additionalData
      console.log("<p>" +data.title +": " +data.message +"\n\nDebuging Details:\n" +JSON.stringify(data) +"</p>" );

      // alert(data.title +": " +data.message +"\n\nDebuging Details:\n" +JSON.stringify(data));
      switch(device.platform)
      {
        case "Android":
          info['msgid'] = data.additionalData.custom_field_1;   // android
          info['vibrate'] = data.additionalData.vibrate;  
          navigator.vibrate(1000, 3000, 1000, 3000, 1000);
          break;

        case "iOS":
          info['msgid'] = data.additionalData["gcm.notification.custom_field_1"];
          info['vibrate'] = data.additionalData["gcm.notification.vibrate"];
          navigator.vibrate(1000);
          push.finish(function() {
            // ios only console.log("processing of push data is finished");
          });
          break;
      }

  });
macdonst commented 8 years ago

@ppetree hey, apparently I'm not very good at writing documentation as you've mis-understood what I've written. I'd like to clarify the docs then and perhaps you can help me by indicating where I went wrong.

So you have a number of things but let me try and address them all:

var push = PushNotification.init({
    android: {
        senderID: "12345679",
        sound: true,
        vibrate: true
    },
    ios: {
        alert: "true",
        badge: true,
        sound: 'false'
    }
});

If this anser helps, please help me make the docs better.

ppetree commented 8 years ago

Funny. I woke up this morning and realized (before coffee even) that I had forgotten to include the initialization code. It's here:

var push = PushNotification.init({ android: { senderID: "35xxxxxxxxx", sound: true, vibrate: true, clearNotifications: true, // clear notifications from shade on app start forceShow: true // ?? }, ios: { senderID: "35xxxxxxxxx", alert: true, badge: true, sound: true // sandbox: true }, windows: {} });

The documentation shows // data.message, // data.title, // data.sound, // data.image, // data.count, // data.additionalData

One of the reasons I included both sides is that there is scant little documentation on sending through GCM to this plugin. It's mostly trial and error and I think, by the time most developers get it working, they never have time to post and help others. Hopefully, this will help those who come behind me.

I did notice there is also a difference between 'sound' and 'soundName' - these little platform dependencies are not obvious. From the docs, I really expected the plugin was going to 'harmonize' the two platforms so that I only had one set of code to deal with.

Also, that may account for why I wasn't getting any sound on the Android but not why I'm not getting any sound on the iOS devices. I question whether sound: true = sound: "true" = sound: default = sound = "default.

It is also completely unclear to me how to pass or play custom sounds.

Thanks for working on a Saturday...

macdonst commented 8 years ago

@ppetree Don't get the PushNotification.init() parameters confused with the payload to the on('notification') event handler. The first controls the plugin behaviour. The second is the data received from the remote messaging system.

The GCM support on iOS is not great but since Google has deprecated GCM in favour if Firebase Cloud Messagin (FCM) we've decided just to make FCM support in v2.0.0 better instead of focusing on a deprecated method.

On Android when you send the payload you would use soundname but you can also use sound as I check both properties when the push arrives. Yes, the plugin harmonizes the client side API. I can't do anything about making the server side harmonized. Both GCM and APNS expect their payloads in a certain format.

If you use:

var push = PushNotification.init({
    android: {
        senderID: "12345679",
        sound: true,
        vibrate: true
    },
    ios: {
        alert: "true",
        badge: true,
        sound: 'false'
    }
});

and send this payload to Android:

{
    "registration_ids": ["my device id"],
    "data": {
        "title": "Default",
        "message": "Plays default notification sound",
        "sound": "default"
    }
}

you should hear the default sound when the application is in the background.

For iOS using GCM the payload would be:

{
    "registration_ids": ["my device id"],
    "notification": {
        "title": "Default",
        "body": "Plays default notification sound",
        "sound": "default"
    }
}

Note on Android the object is called data and on iOS it is called notification. Stupid that we have to do this but hoping it is fixed in FCM.

To play custom sounds they need to be part of res/raw on Android and the bundle on iOS then you just give it the name of the file without extension when you send the push.

ppetree commented 8 years ago

And that has been my issue, no sound is being played on either platform.

I'm using the 2nd custom field to pass in the message type so I can figure out which sound to play from that but was hoping I could just pass in the name... apparently, XDK makes it rather difficult to get the sound files in the correct location.

I won't have another build until Monday... I'll let you know what changing sound to soundname caused on the Android. Still nothing on the ios.

Also, when I get this working, I'll post some .php to gcm code that you can integrate.

macdonst commented 8 years ago

@ppetree oh, XDK. I get you now. Yeah, that will be a pain. Try changing value of sound or soundname from default to ringtone on Android just to make sure the sound property is being picked up. I'm pretty sure this is an issue with XDK not placing the sound files where they are needed in the Android/iOS projects. Maybe @tony-- can comment if he is around.

tony-- commented 8 years ago

@macdonst @ppetree How does the custom sound get included in the project?
Intel XDK build system does not currently support hooks, but if the sound file is declared in plugin.xml it should get installed to the right place, e.g.:

<?xml version="1.0" encoding="UTF-8"?>

<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
    xmlns:rim="http://www.blackberry.com/ns/widgets"
    xmlns:android="http://schemas.android.com/apk/res/android"
    id="intel-xdk-custom-sound-installer-test"
    version="0.0.1">
    <name>Custom Sound Installer</name>
    <description>Test installing custom sounds to res/raw</description>

    <platform name="android">
        <source-file src="xdkbeep.wav" target-dir="res/raw" />
    </platform>

</plugin>

I just tested using a plugin similar to the above with the Intel XDK build system and the resulting .apk had res/raw/xdkbeep.wav:

[~/Downloads/phonegap-push-issue-1147.cordova.crosswalk.201608082523]$ tar -tvf cordova_project-armv7.android.20160808152750.apk | grep beep
-rwxrwxrwx  0 0      0        9702 Aug  8 15:25 res/raw/xdkbeep.wav

One thing to keep in mind with Android is that different devices support different sound formats. Even if the sound file is in the right place, it might not play if it is in the wrong format.

ppetree commented 8 years ago

@tony @macdonst

Great info... certainly leads to an awesome workaround.

When you modify the plugin.xml and add the xdkbeep.wav, where do you need to put the wave file so that it gets picked up and included in the build? My guess is somewhere in the plugin directory but I wouldn't know exactly where.

In my case there are only two custom sound files... one sounds like the emergency broadcast alert you hear on the radio or TV and the other like three short bwerps from a siren when you're getting pulled over.by the police. The rest of the alerts can be the normal/default sound... which is played on the iPhone and iPad but still not on the @macdonst Android device.

On Mon, Aug 8, 2016 at 11:35 AM, Tony Homer notifications@github.com wrote:

@macdonst https://github.com/macdonst @ppetree https://github.com/ppetree How does the custom sound get included in the project?

Intel XDK build system does not currently support hooks, but if the sound file is declared in plugin.xml it should get installed to the right place, e.g.:

<?xml version="1.0" encoding="UTF-8"?>

<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:rim="http://www.blackberry.com/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" id="intel-xdk-custom-sound-installer-test" version="0.0.1">

Custom Sound Installer
<description>Test installing custom sounds to res/raw</description>
<platform name="android">
    <source-file src="xdkbeep.wav" target-dir="res/raw" />
</platform>

I just tested using a plugin similar to the above with the Intel XDK build system and the resulting .apk had res/raw/xdkbeep.wav:

[~/Downloads/phonegap-push-issue-1147.cordova.crosswalk.201608082523]$ tar -tvf cordova_project-armv7.android.20160808152750.apk | grep beep -rwxrwxrwx 0 0 0 9702 Aug 8 15:25 res/raw/xdkbeep.wav

One thing to keep in mind with Android is that different devices support different sound formats. Even if the sound file is in the right place, it might not play if it is in the wrong format.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/phonegap/phonegap-plugin-push/issues/1147#issuecomment-238275942, or mute the thread https://github.com/notifications/unsubscribe-auth/AA8hkSrWb3TcxRITbjnzaytI0bD5L3pfks5qd0zagaJpZM4JeDZ5 .

tony-- commented 8 years ago

@ppetree Plugin file location is relative to the root directory of the plugin. As written in the example, the files would go in the root of the plugin directory (in the same directory as plugin.xml).

ppetree commented 8 years ago

Thanks @tony That was my first instinct but I find many things about this process to be counter intuitive. I strongly prefer XDK over the "other" ways but there are parts that just don't add up.

ppetree commented 7 years ago

Okay, I'm circling back around to this... it's the last remaining issue before release.

Adding the sound file to the plugin-push plugin.xml file is a bad idea. If you do this you have to remove the plugin from your project and add it again in order for the sound files to get included. It's far easier to create a simple plugin that does nothing other than install the files. I have done this using this code (for anyone who needs it):

` <?xml version="1.0" encoding="UTF-8"?>

Adding custom sounds to Phonegap XDK builds Add customized sounds to XDK phonegap builds. MIT

`

Now, the .wav soundfiles are indeed installed in the res/raw folder as eas.wav and bwerp.wav. However, I still get no custom sound.

In my push class which sends the push notification via GCM, I have these lines of code. $this->pushMessageAndroid['soundname'] = "eas"; // EAS sound $this->pushMessageApple['sound'] = "eas";

On Android, I get no sound using these settings. However, if I set these lines to "default" then the default sound gets played.

On iOS I get the default sound regardless.

lock[bot] commented 6 years ago

This thread has been automatically locked.