Im working on a ide where I as an admin can send notifications to all my clients(mobile). Ive been searching and found GCM and other services... I want to know if there is any simpler solutions.
I thought about making a rest call from all clients(mobile) to my server every 1 hour to check for new notifications. And if there is, get them and then present those notifications i the clients(mobile).
Polling will result to more battery life consumption and some other extra unnecessary process (as also mentioned in the comments by #MohammedAtif), for example, is when your client app makes the call to your server but ends up empty. The process is wasted since nothing really happened.
GCM doesn't do that. Gonna refer to the official docs on it's flow.
Lifecycle Flow
Send and receive downstream messages.
Send a message. The app server sends messages to the client app:
The app server sends a message to GCM connection servers.
The GCM connection server enqueues and stores the message if the device is offline.
When the device is online, the GCM connection server sends the message to the device.
On the device, the client app receives the message according to the platform-specific implementation. See your platform-specific documentation for details.
Receive a message. A client app receives a message from a GCM connection server.
Also announced in the recent I/O 2016, GCM's successor is now Firebase Cloud Messaging, which not only has the Push Notification Service, but also has other features (one example is Analytics) for free.
So overall, using GCM (or FCM) is a simpler method than polling. It handles the queuing of the messages you sent, and some others.
Related
I am using GCM for Chat App. If User is Offline(not Connected to App but internet is active) then i Send push notification to devices It receive perfectly.
But when Device is totally offline(neither connected to App and nor active internet) at that time GCM send me response like { id: XXXXXXXX,success: 3,failure: 2{message_id:xxxxx,ect:..}} on my App server.
two device are totally offline they don't have active internet connection..
when device will connect to internet GCM Send them message.
but how can my App server will Know that Message is delivered by GCM.
I Search a lot but can't get any satisfied answer.
I tried that on messageRecive at client device(Android device) i will send httpRequest to my App server but it not suitable for my app it makes App very slow.
So Question is how Can i know that my failure 2 message are delivered.
First of all, you do not need to update your app server in case of a downstream message after it is sent to GCM Server. As explained here, GCM server stores the message in case of an offline device and delivers it once the device is online.
(Now assuming that what you want is to handle network tasks on the client)
You can use GcmNetworkManager to batch network discovery and connectivity related tasks across the system through Play Services. Go through the documentation.
You can use GCM Statistics and Diagnostics from Google Play Developer Console, too. This gives you details of messages handled by a particular app (through Registration token) down to status of specific messages (through message IDs). More explanation here.
(However I am not too clear exactly what you want)
EDIT
but how can my App server will Know that Message is delivered by GCM.
Sorry, reading through again I realised this is the real question. Answer is pretty straight forward here.
.
I am trying to understand the concept of gcm upstream messaging.
Well what I came to know till now after browsing for hours is this :
1)My client app sends upstream message to gcm server.2)GCM server then sends it to my 3rd party app server.3rd party app server responds to it my sending ACK to GCM server.3)Then GCM server echoes the message to the recipient device(recipient Id is included in the upstream message sent from the app).
I don't if its what actually happens.
Now that I am sure that in some step GCM server sends mesaage to my server, how actually GCM server
sends message to my app server. How does it come to know about my app server as there is nowhere where we put my server's address
I have searched the whole Internet but couldn't find anything about this.I have gone through several SO questions but I couldnot find my answer.
I want to know the entire series of steps what happens during this entire process. I am very confused.I want to know the entire concept and what's going on behind all this.
Any detailed explanation with all steps will be appreciated.
To inform I have read the Google docs.
You have much of the flow correct but I think another read of the Docs will clear things up.
Your application server must act as an XMPP client, and connect to CCS (GCM's XMPP server). Your server connecting to CCS is how GCM knows the "address" of your server.
Cleaning up the flow you suggested:
Your app server connects to GCM's CCS.
Your client app (android app) gets a registration token.
Your client app (android app) sends that token to your app server.
Your client app send upstream message to GCM.
GCM fwds that message to your application server.
Your application server send Ack to CCS.
Your application server handles the received message.
Note the above flow is a possible one, there are many others, also downstream messages are not part of the flow. Again refer to the docs for more details.
I want to know which protocol is used to send push notification to android devices and which to send push notification requests to GCM.
Whether it is HTTP, HTTPS or some thing else?
The protocols of the communication between the 3rd party server and GCM server (HTTP or XMPP) were already mentioned in the other answers.
The protocol of the communication between the device and GCM server is not discussed in the GCM documentation, since you never have to access it directly as an Android application developer, and therefore you don't need to know about it.
However, here's a quote from a Google developer from the team that created GCM, which says a few things about the connection. From what he says, you can only know that it's a long-lived TCP connection.
GCM maintains a long-lived connection - and reconnects if it knows the
connection was broken. A router/AP/NAT is supposed to send a FIN or
RST to terminate the TCP connection - so GCM and servers will know the
connection is dead.
However a number of routers and mobile operators don't do this, and
then GCM needs to rely on the heartbeat, ~15 min on Wifi, more on
mobile.
(The quote is taken from an answer by that person)
There are two protocols http and xmpp which you can use to send message to GCM server.
Now its up to you what you want to use. If you want to broadcast message then u should go with http.
you can broadcast 1000 message in a single http request. And only one message through xmpp in a request...
Http can be used only for down streaming(3rd party app server -gcm-mob device)
But gcm won't support up streaming using http.
for that you should use xmpp.Xmpp can be used for both up streamlining and down streaming.
Implementaction of push notification can be very easy if you are going with http and that much more hard if you are going with xmpp.but Google has provided detail tutorial how to implement xmpp.
So please have a look On Google developer site.
Looking at #user3523641's answer and further conversation, I'll try to explain further:
The way of delivering messages is based on the protocol that you've chosen, either HTTP or XMPP (i.e., it's the same). The magic and basic way of working is leaving a socket opened between the GCM server and the user's device.
This way, when an user should receive a message, this opened socket will be used and send the message through itself. This also helps the GCM server knowing which devices are connected or not. So this way, if your third party server says a message should be sent to a user and the GCM server knows the user is not connected, it won't send it at that time, but will try once the connection is again established, so it won't waste connection attempts in vain. The default timeout is 4 weeks, however, it can be changed.
As per the official GCM documentation:
If the device is not connected to GCM, the message will be stored until a connection is established (again respecting the collapse key rules). When a connection is established, GCM will deliver all pending messages to the device, regardless of the delay_while_idle flag. If the device never gets connected again (for instance, if it was factory reset), the message will eventually time out and be discarded from GCM storage. The default timeout is 4 weeks, unless the time_to_live flag is set.
Finally, when GCM attempts to deliver a message to the device and the application was uninstalled, GCM will discard that message right away and invalidate the registration ID. Future attempts to send a message to that device will get a NotRegistered error. See How Unregistration Works for more information.
You can find more info here.
It uses both HTTP and XMPP
When the message is processed successfully, the HTTP response has a 200 status and the body contains more information about the status of the message (including possible errors). When the request is rejected, the HTTP response contains a non-200 status code (such as 400, 401, or 503).
iOS however, requires a dedicated TCP connection on a proprietary port, and GAE environment doesn't allow any external protocol except HTTP over port 80.
The message size limit is 1024 bytes.
Google limits the number of messages a sender sends in aggregate, and the number of messages a sender sends to a specific device
This is how these components interact:
Google-provided GCM Connection Servers take messages from a 3rd-party application server and send these messages to a GCM-enabled Android application (the "client app") running on a device. Currently Google provides connection servers for HTTP and XMPP.
The 3rd-Party Application Server is a component that you implement to work with your chosen GCM connection server(s). App servers send messages to a GCM connection server; the connection server enqueues and stores the message, and then sends it to the device when the device is online. For more information, see Implementing GCM Server.
The Client App is a GCM-enabled Android application running on a device. To receive GCM messages, this app must register with GCM and get a registration ID. If you are using the XMPP (CCS) connection server, the client app can send "upstream" messages back to the connection server. For more information on how to implement the client app, see Implementing GCM Client.
Check out this for more details -->
Google Cloud Messaging for Android (GCM)
Android Cloud to Device Messaging Framework
Cloud Messaging
Cloud to Device Messaging
I am developing mobile client for emailing service. One of the key features is notifications about new messages in the mailbox. As recommended by GCM architecture guidelines we are using a "Pusher" that is responsible for sending messages to the Google servers once we received a new message. The issue is that testing process has reported about serious problems with push notification delivery to devices.
So the question: is there an approaches for monitoring average statistics about push notification delivery percentage, time etc? Or maybe somebody have experience in how to set up test environment for efficient monitoring of how much notifications are getting lost during the application work?
All the "tips&tricks" related to the improving Android GCM experience are welcome.
Google claims that the processing at their GCM server takes less than a millisecond. Link below for a great video on GCM from Google's developer. And it's believable coz I could get push notifications almost instantaneously using my company's server to my device now.
http://www.youtube.com/watch?v=YoaP6hcDctM
They don't guarantee delivery, but they try for a max of 4 weeks to deliver the message depending on the duration you set in the message you send to Google's GCM servers and if you wish to let Google keep the data for eventual delivery of message to the device in case the device was offline when the message was to be delivered.
However, there are certain conditions under which the GCM messages are not delivered.
Background data is unchecked under Account and Sync settings.
Prior to 4.0.4.(ICS), a Google account on the device is a pre-requisite for GCM. Maybe, Users are not logged into their Google account.
The only way to do so is to report back to your server with the timestamp of the received push.
You can either
Report back to the server once you receive the notification in your GCM service. To implement, you will have to add a push id for your push notifications and send the id along with the push data. The client will have to get the timestamp once it receive the message and send it back along with the notification id. A simple php script can be done (when you send a push notification, you set the time of the send-notification and once it receives the device's timestamp it sets the receive-notification. This boils down to two fields in your database (marked in bold). In this approach you will probably not so much care about errors since it is very probable that the device will have a connection when it receives the notification and as such its request to your server will go through.
Keep a list of notifications received in your app and their timestamps. And when the sync is done, send the this data in your sync operation. This is ultimately the same approach but your server's data won't be as realtime as the first approach. However, the extra request is not required from the client's side but saving the received notifications and their timestamps is.
All in all, you will have to keep track of the notifications sent using a notification-id and their sending time (send-notification) and their receive time (receive-notification). A simple query will help you analyze this data.
Google has added support so that you can receive delivery receipts from Cloud Connection Server (CCS):
You can use upstream messaging to get delivery receipts (sent from CCS to your 3rd party app server) when a device confirms that it received a message sent by CCS.
To enable this feature, the message your 3rd-party app server sends to CCS must include a field called "delivery_receipt_requested". When this field is set to true, CCS sends a delivery receipt when a device confirms that it received a particular message.
https://developer.android.com/google/gcm/ccs.html#receipts
Google does not make these statistics available to you. There are some statistics available on the android developer console. This only shows the number of messages and registrations.
You would have to implement your own data collection, which could be done fairly easily. You could record the time & id of each message sent and have your android client report back to your server with the time of message receipt. You could then store the data on your server and query as needed.
Since that time Google has provided developers with advanced monitoring tool.
The Gcm Diagnostic Tool is available in Google Play developer console. Additional information is here https://support.google.com/googleplay/android-developer/answer/2663268
So you can easily track the particular message status via registration token.
Since I want to build reliable communication in mobile apps, could I get push failed reports(maybe device is offline) from the third party push services (C2DM, APN, urban airship) ?
Or We need to build it by ourselves?
The intended purpose of Android C2DM is to be a battery-saving way for your server app to signal the mobile device that it wants to start reliable communications.
You can structure your message so that each new C2DM encompasses everything that has occurred since the last two-way interaction with the server (i.e., "come and get whatever I've got"). Your failed delivery report is implicit in the mobile device not responding promptly (you can do this because you know C2DM activates your app with an Intent).
Is that really any worse than guaranteed delivery of each message in a lossy medium? Okay, it's worse in that you also have to implement a primary communication method. But you had to do that anyway because C2DM is inbound-only, right?
As Vinay says, MQTT may offer you the feature you desire. When a client connects to the server, it can register a "last will and testament" message with the server. If the client disconnects unexpectedly, the server sends this message to the topic it was instructed to do.
In this scheme, your client could send a message "online" to something like client//status and register the message "offline" as a LWT for the same topic. You could then have a server local client that listened to the topic client/+/status and it would know which clients were online and which offline.
I would suggest that the tokudu demo isn't the best place to look. This blog post by Dale Lane gives insight into using MQTT on Android: http://dalelane.co.uk/blog/?p=1599 and there is a review of MQTT power usage (again on Android) at http://stephendnicholas.com/archives/219
There are client implementations to suit both IOS and Android, see http://mqtt.org/software
No one service does not provide reports about failed pushes.
Failed push report makes little sence with APN/C2DM/Helium
All services are aimed to deliver the push-message under all circumstances.
If device is offline now, then push will be delivered when device becomes online.
Moreover, for iOS push-message is just a notification for a user, not for an application!
Simple case will illustrate it:
Assume that push is received when the application is turned off. In that case, notification for the user will occur. But, application will receive data from push, only if user taps on that notification! If user will tap on application's icon, then data will not be received.
So techically, push is delivered to the iOS device and application is started, but data is not delivered.
UrbanAirhip with APN and Helium
You can consider to implement your own transport for pushes. MQTT seems to be a good option.
But in this case, you have to deal with keepalives, device sleeps and battery optimisations.
All that hard work is already done by engineers from Apple, Google and UrbanAirship.
Depending on your business needs, it can be easier to adapt your architecture for existing solutions, then reimplement push-service again.
Take a closer look to UrbanAirship. In fact, C2DM has some limitations and sometimes timings for delivery of push-message is too big. Because of that UA has implemented their own transport - Helium, it works pretty good. Helium is a paid service, but UA provides good SLA.
I am suggesting for push notification IBM MQTT protocol. This fine enough for push notification.
see the demo from https://github.com/tokudu/AndroidPushNotificationsDemo
I did something similar where I had a database keep track of push queues to known subscribers and had reporting when failed. It was very simple and went something like this...
The schema was like so:
pushMessages
messageID , GUID, PK
message , nvarchar (256),
expires , datetime
messageQueues
subscriberID , GUID, PK
messageID , GUID PK
failedPushMessages
subscriberID, GUID, PK
messageID , GUID PK
(subscriber table omitted)
Once a client received the message successfully, the client would ping back to the push server and notify it via the unique queueItems ID that it received on the push notification. There would also be a daily database process that would check for expired push messages. When found, it would do a join on the queueMessages matching the messageID then remove them from the messagesQueues table and copy them to the failedPushMessages table.
This was very easy to understand and maintain but I don't have experience doing it another way.
Push Services are an efficient and reliable way to alert your users. They allow even background applications to inform users of new information in real-time. Push Services are widely used for a variety of fields in mobile applications, such as weather updates, messaging services, mail notification, coupon services, and so on. Push Services are no longer optional but have become essential.