I'm trying to use GCM for IOS and Android clients. It seems to work fine with IOS when app is in the foreground, however, when the app is in the background, the notification center doesn't receive the message and didReceiveRemoteNotification with completionHandler
doesn't get called.
I identified a problem as a wrongly formatted message from GCM to APNS. Namely, that's how it looks:
[message: New message, collapse_key: do_not_collapse, from: **************]While, the IOS push notifications should have
aps
key in the notification, am I right ? As well as content-available set to 1. For example: { "aps" : { "content-available" : 1 }, "data-id" : 345 }
By the way, in the foreground app receives the message anyway, the problem is only with the background. Any advice on how should I approach a problem, to make GCM work for both ios and android?
UPDATE: That is what I found on the net:
Regarding actual communication, as long as the application is in the background on an iOS device, GCM uses APNS to send messages, the application behaving similarly as using Apple’s notification system. But when the app is active, GCM communicates directly with the app
So the message I received in the foreground mode:
[message: New message, collapse_key: do_not_collapse, from: **************]
Was the direct message from GCM(APNS did not participate in this affair at all). So the question is: does APNS reformat what GCM sends to it to adhere to ios notifications format? If so how do I know that APNS actually does something and whether it sends me a notification in different format ? Is there any way to view logs of incoming data from APNS ?
UPDATE: Okay, I managed to change the structure of the message and now in the foreground mode I receive the following message:
Notification received: ["aps": {"alert":"Simple message","content-available":1}, collapse_key: do_not_collapse, from: **************]
Now it seems to be well formatted, but there is still no reaction when the app is in the background. didReceiveRemoteNotifification completionHandler doesn't get called! What should I look for and where can a problem be ? Can the square bracket be a problem for push notification ? To be even more precise, ios doesn't post any alerts/badges/banners from that incoming notification.
Once your client app is installed on a device, it can receive messages through the FCM APNs interface. You can immediately start sending notifications to user segments with the Notifications composer, or messages built on your application server.
From this thread, GCM is a service that helps developers send data from servers to their Android applications on Android devices. Same with APN which is a service for app developers to propagate information to iOS (and, indirectly, watchOS), tvOS, and macOS devices.
Using GCM, your server can notify your app running on a particular device that there is new data available for it. Compared to polling, where your app must regularly ping the server to query for new data, this event-driven model allows your app to create a new connection only when it knows there is data to download.
For every poor soul wondering in quest for an answer to GCM background mystery. I solved it and the problem was in the format. I'm posting the right format as well as Java code needed to send Http request to GCM with some message. So the Http request should have two field in the header, namely:
Authorization:key="here goes your GCM api key" Content-Type:application/json for JSON data type
then the message body should be a json dictionary with keys "to" and "notification". For example:
{ "to": "gcm_token_of_the_device", "notification": { "sound": "default", "badge": "2", "title": "default", "body": "Test Push!" } }
Here is the simple java program (using only java libraries) that sends push to a specified device, using GCM:
public class SendMessage { //config static String apiKey = ""; // Put here your API key static String GCM_Token = ""; // put the GCM Token you want to send to here static String notification = "{\"sound\":\"default\",\"badge\":\"2\",\"title\":\"default\",\"body\":\"Test Push!\"}"; // put the message you want to send here static String messageToSend = "{\"to\":\"" + GCM_Token + "\",\"notification\":" + notification + "}"; // Construct the message. public static void main(String[] args) throws IOException { try { // URL URL url = new URL("https://android.googleapis.com/gcm/send"); System.out.println(messageToSend); // Open connection HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // Specify POST method conn.setRequestMethod("POST"); //Set the headers conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("Authorization", "key=" + apiKey); conn.setDoOutput(true); //Get connection output stream DataOutputStream wr = new DataOutputStream(conn.getOutputStream()); byte[] data = messageToSend.getBytes("UTF-8"); wr.write(data); //Send the request and close wr.flush(); wr.close(); //Get the response int responseCode = conn.getResponseCode(); System.out.println("\nSending 'POST' request to URL : " + url); System.out.println("Response Code : " + responseCode); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); //Print result System.out.println(response.toString()); //this is a good place to check for errors using the codes in http://androidcommunitydocs.com/reference/com/google/android/gcm/server/Constants.html } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With