phonegap / phonegap-plugin-push

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

iOS: on('notification') event not firing on background mode #1833

Open iparrabb opened 7 years ago

iparrabb commented 7 years ago

Expected Behaviour

"on('notification')" event is triggered on background mode

Actual Behaviour

"on('notification')" event is triggered only when app is in foreground or when app received a notification and user clicked it.

Reproduce Scenario

[Only on iOS] The app works with Ionic 2 and FCM on Android and iOS, but when a notification is received, if you click on it, the app launches and notification plugin triggers the "on('notification')" event. But if you just runs the app, after receiving a notification, the event doesn't trigger.

I have read the information about the payload but it does not work.

Platform and Version

iOS                                    10.3.2

Cordova CLI version and cordova platform version

cordova --version                                    7.0.1

Plugin version

cordova plugin version | grep phonegap-plugin-push   1.10.5

Sample Push Data Payload

$msg = [
    'body'  => $notification_request->message,
    'title' => $notification_request->title,
    "badge" => 1,
    "payload" => [
        "published" => Carbon::parse($not->created_at)->format('d/m/Y H:i'),
    ]
];
$body = [
    'registration_ids' => $registrationIds,
    'priority'  => 'high',
    'notification' => $msg,
    "aps" => [
        "content-available" => 1
    ],
    'notId' => $not->id,
];

$headers = [
    'Authorization:key=FCM-TOKEN',
    'Content-Type: application/json'
];

$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://gcm-http.googleapis.com/gcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $body ) );
curl_setopt($ch, CURLOPT_FAILONERROR, TRUE);
$result = curl_exec($ch);
curl_close( $ch );

Sample Code that illustrates the problem


pushOptions: PushOptions = {
  android: {
    senderID: "FCMSENDERID",
    forceShow: true
  },
  ios: {
    senderID: "FCMSENDERID",
    gcmSandbox: true,
    alert: true,
    badge: true,
    sound: true,
    clearBadge: true
  }
};

const pushObject = this.push.init(pushOptions);

pushObject.on('notification').subscribe((notification: NotificationEventResponse) => {

  pushObject.finish().then(() => {
      let toast = this.toastCtrl.create({
        message: 'Notificación importante:\n' + notification.title,
        duration: 30000,
        position: 'bottom',
        showCloseButton: true,
        closeButtonText: 'Cerrar'
      });
      toast.present();
  });
});

Logs taken while reproducing problem

Logs not working when app is in background.

Thanks.

iparrabb commented 7 years ago

Which is my mistake?, I'm testing the notifications but when the app is closed ONLY ON iOS doesn't work.

Server side code:

if($token->platform === 'ios') {
    $data = [
        'to' => $token->device_token,
        'notification' => [
            'body'  => $notification_request->message,
            'title' => $notification_request->title,
            "content_available" => true,
        ],
        "aps" => [
            "content-available" => 1,
        ],
        "priority" => 'high',
        "data" => [
            "published" => Carbon::parse($not->created_at)->format('d/m/Y H:i'),
        ],
        'notId' => $not->id,
    ];
} elseif ($token->platform === 'android') {
    $data = [
        'to' => $token->device_token,
        'data' => [
            'body'  => $notification_request->message,
            'title' => $notification_request->title,
            'icon'  => 'ic_stat_airplanemode_active',
            'notId' => $not->id,
            "content-available" => "1",
        ],
        "priority" => "high",
    ];
}

I followed the steps of #1828.

iparrabb commented 7 years ago

@fredgalvao @macdonst any help please?????

macdonst commented 7 years ago

@iparrabb try the following for iOS:

if($token->platform === 'ios') {
    $data = [
        'to' => $token->device_token,
        'notification' => [
            'body'  => $notification_request->message,
            'title' => $notification_request->title
        ],
        "content_available" => true,
        "priority" => 'high',
        "data" => [
            "published" => Carbon::parse($not->created_at)->format('d/m/Y H:i'),
        ],
        'notId' => $not->id,
    ];
}

Sending to iOS via GCM/FCM requires we follow https://developers.google.com/cloud-messaging/http-server-ref#downstream-http-messages-json and I should update the docs.

iparrabb commented 7 years ago

Thanks for your reply @macdonst, I can test this snippet but the result is the same.

Foreground Android and iOS ¡OK! Background Android and iOS ¡OK! App closed Android ¡OK! iOS ¡FAILED!

I tested too with APNS instead of FCM without lucky, same result.

talvespe commented 6 years ago

Hi, @iparrabb i'm facing the same issue.

App closed Android ¡OK! iOS ¡FAILED!

Did you find some fix for that?

shankari commented 6 years ago

wrt https://github.com/phonegap/phonegap-plugin-push/issues/1833#issuecomment-314152890 if the app is force-killed on iOS, no notifications are delivered by the OS.

You have to use pushkit to get around that, and it is hard because pushkit is only supported for three use cases.

https://developer.apple.com/documentation/pushkit

If your app isn't running, the system automatically launches it upon receiving the notification. Although you can also use silent user notifications to update your app in the background, your app isn't guaranteed to launch when a notification arrives. For more information, see Local and Remote Notification Programming Guide.

iparrabb commented 6 years ago

@shankari thanks a lot, currently the app is published in the app and play stores, on the next version I need to check this behavior.

iparrabb commented 6 years ago

@talvespe, check the reply of shankari.

talvespe commented 6 years ago

@iparrabb thanks in advance i'll check and let u know.

andymurakami commented 6 years ago

If a send : $resposta = shell_exec('curl -X POST --header ' . '"Authorization: key=AAAAaUS7Nr4:APA91bHj3O-F4xyGheS2Umk6ZmJBfighcGBd_VTvsih7lAvJNGWyfd5udZVv_Bqchrq6I1Iim6BFRe_IxH1UANbetVb0ojAHx6vl-v4iP-5OzXtJ3tkixSlSZqWtZO6PhIYHJo5E0cBELVlv3kVDzbAF5e_iCqE_Bw"' . ' --header' . ' "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d ' . '"{\"registration_ids\":\"' . $registrationIds . '\",' . '\"priority\":\"high\",' . '\"content-available\":\"true\",' // . '\"notification\":{\"body\": \"Teste 646\",\"title\": \"teste\", \"id_oferta\": \"646\" }}"'); . '\"data\":{\"body\": \"646\",\"title\": \"teste\", \"id_oferta\": \"646\" }}"');

The event on('notification' is OK !

If a use: $ch = curl_init (); curl_setopt ( $ch, CURLOPT_URL, $url ); curl_setopt ( $ch, CURLOPT_POST, true ); curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers ); curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt ( $ch, CURLOPT_POSTFIELDS, $fields );

not fired.

if a use: $resposta = shell_exec('curl -X POST --header ' . '"Authorization: key=AAAAaUS7Nr4:APA91bHj3O-F4xyGheS2Umk6ZmJBfighcGBd_VTvsih7lAvJNGWyfd5udZVv_Bqchrq6I1Iim6BFRe_IxH1UANbetVb0ojAHx6vl-v4iP-5OzXtJ3tkixSlSZqWtZO6PhIYHJo5E0cBELVlv3kVDzbAF5e_iCqE_Bw"' . ' --header' . ' "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d ' . '"{\"registration_ids\":\"' . $registrationIds . '\",' . '\"priority\":\"high\",' . '\"content-available\":\"true\",' . '\"notification\":{\"body\": \"Teste 646\",\"title\": \"teste\", \"id_oferta\": \"646\" }}"'); // . '\"data\":{\"body\": \"646\",\"title\": \"teste\", \"id_oferta\": \"646\" }}"'); not fired to

stale[bot] commented 6 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.