Skip to content
This repository has been archived by the owner on Sep 4, 2020. It is now read-only.

Using this Plugin with Parse.com results in not showing Push on Android #147

Closed
Mojo90 opened this issue Sep 16, 2015 · 16 comments · Fixed by #220
Closed

Using this Plugin with Parse.com results in not showing Push on Android #147

Mojo90 opened this issue Sep 16, 2015 · 16 comments · Fixed by #220

Comments

@Mojo90
Copy link

Mojo90 commented Sep 16, 2015

I am experiencing a problem with Parse.com and iOS / Android Push-Plugin.
What I am doing is: sending from parse.com a push notification to iOS and Android devices with this Backend-command:

Parse.Push.send({
where: query, // Set our Installation query
data: {
alert: message
}
}

So the type of this Notification is "alert". On iOS it is showing with no problem on Lockscreen or as Banner. But not on Android. If App is in Background I receive this on Console:

V/GCMBroadcastReceiver﹕ onReceive: com.google.android.c2dm.intent.RECEIVE
V/GCMBroadcastReceiver﹕ GCM IntentService class: com.adobe.phonegap.push.GCMIntentService
V/GCMBaseIntentService﹕ Acquiring wakelock
V/GCMBaseIntentService﹕ Intent service name: GCMIntentService-GCMIntentService-15
D/PushPlugin_GCMIntentService﹕ onMessage - context: android.app.Application@41bcf068
V/GCMBaseIntentService﹕ Releasing wakelock
(Related to this Issue: #86)

But nothing is showing up in Notification Center. As well I tried type "message" (as stated in #86) or "data" but nothing else happened. But if Android App is open I can receive type "alert" and show it via "alert(data.additionalData.data.alert)". Is this normal behavior? Because I'd like to have with the same command from my backend that the push is showing on android and ios. While I tried "message" and "data" it didn't show up on ios either. So how can I make Android showing up type "alert" in Notification Center and as Banner? Thanks!

@smdvdsn
Copy link
Collaborator

smdvdsn commented Sep 16, 2015

Right now this plugin will not work with Parse.com see my comment here #54 (comment)

I've not had a chance to revisit my fork but you could make your own. You need to modify the GCMIntentService.getString methods to also look in the "data" object.

Here is my code to get the message if it helps. I also support Urban Airship.

    protected static String getMessage(Bundle extras) {
        if ( extras.getString("message") != null ) {
            return extras.getString("message");

        } else if ( extras.get("com.urbanairship.push.ALERT") != null ) {
            return extras.getString("com.urbanairship.push.ALERT");

        } else if ( extras.get("data") != null ) {
            Object json = extras.get("data");
            // Make sure data is json object stringified
            if ( json instanceof String && ((String) json).startsWith("{") ) {
                try {
                    // Parse it
                    JSONObject data = new JSONObject((String) json);
                    if (!data.isNull("alert")) {
                        return data.getString("alert");
                    }
                } catch( JSONException e) {
                    Log.e(LOG_TAG, "extrasToJSON: JSON exception");
                }
            }
        }

        return null;
    }

@macdonst
Copy link
Member

@smdvdsn like I said in #54 I'd be interested in your fork. You can send a PR or just post the URL so I can review.

@Mojo90
Copy link
Author

Mojo90 commented Sep 16, 2015

@smdvdsn Great Thanks!!
Tested it and worked. Only have to fix the icon because this is too big...

To be clear: I updated the function "private String getMessageText(Bundle extras)" with your code in File GCMIntentService and seems to work. Great!

@macdonst
Copy link
Member

@Mojo90 it's a work around for now but I'd like to inspect the data coming from Parse so we can extract the other keys besides 'message'.

@Mojo90
Copy link
Author

Mojo90 commented Sep 16, 2015

Okay. Yep I understand. But does work for me right now because I only need to inform the users.
I think one should not do anything more than that because the manufacturer states that Push is not reliable...

@Mojo90
Copy link
Author

Mojo90 commented Sep 17, 2015

But another thing: is it possible to set title in init like so?

var push = PushNotification.init({ 
                "android": {"senderID": "XXX",
                            "icon": "icon_notification",
                            "title": "Meet Friends"},
                "ios": {},
                "windows": {}
            });

Because Title is not shown on push notification. And I also use Local Notification Plugin there everything shows just fine. Also tried to set title via parse.com like so:

Parse.Push.send({
    where: query, // Set our Installation query
    data: {
        alert: message,
        title: "Meet Friends"
    }
}

but didn't work. Title on device was just not there

@smdvdsn
Copy link
Collaborator

smdvdsn commented Sep 17, 2015

@Mojo90 To get the title on your push you just need to add similar custom code to the getString methods. If the key passed to getString == TITLE then look in the "data" object as per your modified getMessageText method.

@macdonst unfortunately I've not been able to find the time to revisit this. I'm currently using the code I posted here but I don't think we should merge that in to master. I still think the best approach is to allow the keys to be configured as per my comment on #54 . I worry that we'll end up just chasing our tails trying to support every random push service out there.

Thanks for all your work on this plugin. It's working great for me and if I manage to find some time I will send that PR.

@Mojo90
Copy link
Author

Mojo90 commented Sep 17, 2015

@smdvdsn mhh I tried but couldn't get it to work. so I see in console.log that in addition to alert there is the title set.

what I tried in getMessageText is:

else if(extras.getString("title") != null){
            return "Meet Friends";
        }

and

else if(extras.getString("title") != null){
            Object json = extras.get("data");

            if ( json instanceof String && ((String) json).startsWith("{") ) {
                try {
                    // Parse it
                    JSONObject data = new JSONObject((String) json);
                    if (!data.isNull("title")) {
                        return data.getString("title");
                    }
                } catch( JSONException e) {
                    Log.e(LOG_TAG, "extrasToJSON: JSON exception");
                }
            }
        }

and

else if(extras.get("title") != null){
            return "Meet Friends";
        }

but title never shows up. Do you have one more hint how to return the title correctly?

@smdvdsn
Copy link
Collaborator

smdvdsn commented Sep 17, 2015

@Mojo90 from current master try replacing the two getString methods and the getMessageText method with this. I've not tested or compiled this but it should work. This will look for all keys in the data object that Parse sends if they are not found directly. It also adds the "alert" key to the getMessageText method.

    private String getString(Bundle extras,String key) {
        return getString(extras, key, null);
    }

    private String getString(Bundle extras,String key, String defaultString) {
        String message = extras.getString(key);
        if (message == null) {
            message = extras.getString(GCM_NOTIFICATION+"."+key, defaultString);
        }

        if ( messge == null ) {
            // Look in data object
            Object json = extras.get("data");
            // Make sure data is json object stringified
            if ( json instanceof String && ((String) json).startsWith("{") ) {
                try {
                    // Parse it
                    JSONObject data = new JSONObject((String) json);
                    if (!data.isNull(key)) {
                        return data.getString(key);
                    }
                } catch( JSONException e) {
                    Log.e(LOG_TAG, "extrasToJSON: JSON exception");
                }
            }
        }
        return message;
    }

    private String getMessageText(Bundle extras) {
        String message = getString(extras, "alert");
        if (message == null) {
            message = getString(extras, MESSAGE);
        }
        if (message == null) {
            message = getString(extras, BODY);
        }

        return message;
    }

@macdonst
Copy link
Member

@smdvdsn this is exactly why I want to take a closer look at it. Instead of modifying every getXXX() method in GCMIntentService I want to detect it is a Parse push and use the data object inside the data object in the onMessage method to be passed to createNotification.

@Mojo90
Copy link
Author

Mojo90 commented Sep 17, 2015

@smdvdsn Great! good Workaround, does for me work right now and is exactly what I need! THANK YOU!

@smdvdsn
Copy link
Collaborator

smdvdsn commented Sep 17, 2015

@macdonst I agree. I just wanted to give Mojo90 something to solve his issue. As I said I don't think this should be merged in.

I think it would be good to consolidate all of this logic in the PushPlugin.convertBundleToJson method so that we don't have to duplicate the alternate keys everywhere. So in GCMIntentService.onMessage you call PushPlugin.convertBundleToJson and then pass the JSONObject around instead of the extras. convertBundleToJson should normalise all the keys to our known values "title", "message" etc

Again I really think the keys need to be configurable. There are just too many different services. Urban Airship for instance doesn't use a nested object like Parse, they prefix their keys. The message is under "com.urbanairship.push.ALERT" for instance. I worry that the branching logic and list of keys to check will get out of hand.

@macdonst macdonst added this to the Release 1.4.0 milestone Oct 1, 2015
smdvdsn added a commit to smdvdsn/phonegap-plugin-push that referenced this issue Oct 13, 2015
This change moves all alternative key logic into a single method. Also allows message keys to be in nested "data" or "message" object to support parse.com and other providers.

fixes phonegap#147 replaces phonegap#218 and phonegap#182
smdvdsn added a commit to smdvdsn/phonegap-plugin-push that referenced this issue Oct 13, 2015
This change moves all alternative key logic into a single method.
Allows message keys to be in nested in "data" or "message" object. This is to support parse.com and other providers.
Added additional keys to support Urban Airship.

fixes phonegap#147 replaces phonegap#218 and phonegap#182
@smdvdsn
Copy link
Collaborator

smdvdsn commented Oct 13, 2015

@macdonst I've finally managed to find the time to revisit this. I've created a PR #220 that should be a good starting point for this. It moves all alternate key logic into a single method.

@macdonst
Copy link
Member

@smdvdsn Awesome, thanks for the PR. I'm going to look at it today.

@iori57
Copy link

iori57 commented Jun 4, 2016

I think I found a bug, can someone verify this? It is related to the solution provided by this issue (I saw the issue number inside the code comments)

In GCMIntentService.java
at line 167 right after the closing bracket of the while loop, I think it is missing a 'continue;' just like the one in line 185.

Without this 'continue;', it will jump out of the if statement and run replaceKey(key, newKey, extras, newExtras);, which reverts whatever the while loop has just did..

Update: Seems like it only causes problem when the key is 'message' and it is a json object with yet another 'message' within it.

@lock
Copy link

lock bot commented Jun 4, 2018

This thread has been automatically locked.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 4, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

Successfully merging a pull request may close this issue.

4 participants