phonegap / phonegap-plugin-push

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

Silent push does not execute Javascript on background while using force-start #2066

Open tom-kraak opened 6 years ago

tom-kraak commented 6 years ago

Expected Behaviour

Whenever a silent push notification is received after the app was killed, it should force start it to the background and execute an API request by using an Ajax call.

Actual Behaviour

Whenever a silent push notification is received after the app was killed, it is being force started to the background, but not executing the API request through Ajax untill the app is opened on the foreground.

Reproduce Scenario (including but not limited to)

  1. Send a silent push with force-start:"1" and content-available:"1".
  2. In the notification callback, try to make a request which stores something in your backend database.
  3. Check if any value is stored while app is forced start in background. (In my case it isn't)
  4. Check if any value is stored when app is opened from background to foreground. (In my case it is)

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

Android 7.0 (For Huawei) Android 6.0.1 (For One Plus Two)

(Android) What device vendor (e.g. Samsung, HTC, Sony...)

Huawei Ascend P10 (I made sure it is not a 'protected app') One Plus Two

Cordova CLI version and cordova platform version

Cordova version: 6.5.0 Cordova Android version: 6.1.2

Plugin version

1.9.0

Sample Push Data Payload

{ "force-start":"1", "content-available":"1", "some-custom-var":20 }

Sample Code that illustrates the problem

// Define global push:
var push;
// Listen for device ready event:
document.addEventListener('deviceready', deviceReady, false);

// Register device:
function deviceReady(){
    // Register push:
    push = PushNotification.init({
        android: {
            senderID: "MY_SENDER_ID" // Project number in google developer console
        },
        ios: {
            alert: "true",
            badge: "true",
            sound: "true"
        },
        windows: {}
    });

    // Set callback:
    push.on('notification', onNotification);
    // Register callback:
    push.on('registration', onDeviceRegistered);
    // Error callback:
    push.on('error', function(e) {
        // e.message
        console.log("Error in push notification:" + e.message);
    });
}

// Simplified sample of making an API call on receiving push
function onNotification(data){
    // Make a request
    $.ajax({
        url: 'http://my-custom-domain.com/api/test',
        type: 'post',
        dataType: 'json',
        data: {
            customVar : "I Received push, store this message on backend"
        },
    })
    .done(function(response){
        // Done, finish push:
        push.finish(
            function(){
                console.log('Finished');
            },
            function(){
                console.log('Finished with failure');
            }
        );
    })
    .fail(function(){
        console.log('Failed API call');
    });
}

// Simple on device registered callback
function onDeviceRegistered(data){
    // Store the token on the backend
    // No example given... Just a simple HTTP request
}    

Logs taken while reproducing problem

None

macdonst commented 6 years ago

@tom-kraak can you please test with the latest version of the plugin to see if the issue still exists?

tom-kraak commented 6 years ago

@macdonst I just tested it with the latest v1.x version (1.10.5), but it gives the same results as 1.9.0. As I read it, push on versions 2.x are using Firebase as a service, which my backend currently does not (I am using GCM).

tom-kraak commented 6 years ago

@macdonst I swapped over the backend service to work with Firebase and implemented the version 2.0.0 in the app by using the google-services.json. I just tested it, the exact same behaviour is still happening. The app still opens on the background with a 'black screen', like the webview is not being executed at all.

I can't swap over to a newer version of the plugin, because Phonegap build does not support the higher version of Cordova yet.

An important thing I noticed is that the deviceready callback is never being executed, thus not executing any other code, that should be done after the event. Hope this clears up alot. Code that is not waiting for the deviceready callback does execute. But the push related code, must wait for the deviceready event

tom-kraak commented 6 years ago

@macdonst Just tested the code on iOS. Very similar behaviour.

iOS silent push does work when:

  1. App is open in the foreground;
  2. App is open in the background.

iOS silent push does not work when:

  1. App is force closed;

The payload for iOS is as following: { "aps": { "content-available": 1, "additionalData": { "id": 4 } }, "notId": 1513611593 } I have the feeling that the 'device ready callback' is not called on iOS either if the app was force closed (just as Android).

This is also a very crucial part for the app I'm working on for a client and I would like to give an estimation to him. Could you give any estimation when you plan to retest and possibly solve the issue?

Looking forward to your reply.

Kind regards,

Tom

DaDanny commented 6 years ago

@tom-kraak Did you ever get this resolved?

FYI, last I checked, the intended behavior for iOS silent notifications is that if an app has been force-closed by a user, that app cannot launch in the background from a silent notification until the app has been relaunched by the user. This is the intended behavior from Apple, so every app is affected, not just ones utilizing this plugin.

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.