Push notifications can be a great way to engage your app’s users. That’s why a lot of our clients are interested in implementing push notifications in their apps.
Push notifications keep users informed about relevant information and important updates. Moreover, they remind users of the app’s existence and tend to improve retention metrics. Whether your app is running in the background or is inactive, push notifications will make sure that relevant information delivered on time, providing value for users and convertible actions for product owners.
We wrote this post to break down the technology lying underneath pushes, and to address the issues a developer should keep in mind when building push notification features.
Google Cloud Messaging (GCM)
There are a lot of services offering push notifications on Android. The majority are based on Google Cloud Messaging, complementing and expanding its original functionality. GCM is a Google Play Service that lets you transmit information from a server to an Android device and vice versa over one connection. What kind of “information” can we transmit over GCM?
GCM handles (1) lightweight messages that inform an Android app that there are incoming data ready to be downloaded from the server (eg. “a new message”) or (2) messages with data payloads not exceeding 4KB (eg. text messengers can transmit data directly). The priority of push notification delivery is managed by the GCM service.
GCM is free to use without any limits as to the number of push notifications. You can read more about implementing push notifications using GCM here.
Firebase Cloud Messaging (FCM)
FCM lets you subscribe for push notifications and exchange data with a single separate device or even among a few devices that belong to one user.
Here’s how it works:
If a push notification was opened on one device, it will vanish from all other devices. When we go to our tablet we don’t want to see “new” notifications that we already read on our phone a few hours ago.
Devices can exchange pushes with each other by sending them to the server with a notification key. This lets you synchronize actions, like alerts on your multiple mobile devices.
GCM Cloud Connection Server (ССS)
An Android device sends a sender ID and application ID to GCM server for registration.
Upon successful registration, GCM server issues registration ID to Android device.
After receiving registration ID, the device will send the registration ID to your server.
Your server will store the registration ID in the database for later use.
Whenever a push notification is requested, your server sends a message to the GCM server along with the device registration ID (stored in the database).
The GCM server will then deliver that message to the respective mobile device according to the device registration ID.
NOTE: To use GCM, in addition to its implementation in the mobile app, you will have to implement it on the server side as well. Also you will have to implement the sending of a device’s registration_id from the mobile app to the server.
Alternatives (Typically for both iOS & Android)
There are other services that either extend the possibilities of FCM or develop their own custom solutions that don’t rely on Google Play Services. Some of these alternatives are Carnival and Urban Airship. The advantage of these alternate services is that they can be used cross-platform. However, the functionality they provide can be too extensive for some basic use cases.
It makes sense to use services like Parse if you want all the functionality it offers or if your own implementation of push notifications would be too costly. On the other hand, Parse can be overkill for basic push functionality.
Push notifications on iOS
iPhone push notifications work similarly to Android push notifications. Here’s what they can do:
Transmit a short text message
Play a short sound
Set a badge count on an app’s icon
You don’t have to use all these functionalities – only the ones you require.
Apple push notifications architecture
These are the steps for delivering a push notification in iOS:
iOS requests a device token from Apple Push Notification Service (APNS).
The app receives the token, which functions as the address to send a push notification to.
The app sends the token of the device to your server.
When prompted, the server will send a push notification with a device token to the APNS.
APNS will send a push notification to the user’s device.
What must you do to enable push notifications for iOS? First, you need to create a provisioning profile and SSL certificate for the server. Push notifications are always sent by the server. You need to launch the background implementation on the server, install an SSL certificate, and set up an outgoing TLS connection on certain ports.
Check out: App Development Cost
Badge issue handling
A badge is a little red circle in the top right corner of your iOS app icon that tells a user when there is some information waiting to be read (a new message, news, an event, a missed call, etc.) A badge also indicates the number of unread messages or notifications.
NOTE: Though badges are exclusive to iOS, there are a number of custom ways to implement Android GCM badges.
However, there is one problem with badge notifications: the number indicated on the badge may not coincide with the number of messages inside the app. For example, the badge on your app’s icon may show two unread messages, but when you open the app there are five.
This is confusing for users. It’s especially irritating, however, when a badge shows a new message that doesn’t exist in the app. And users can’t manually clear message counts unless you specifically build that functionality into your app. To keep your users sane, bind the number of incoming messages with the badge count. Don’t let them live separate lives!
The server's role in the badge count
It’s not just iOS developers who responsible for badge counts. Badge counts come from the server. Apps typically have unread notification counts maintained on the server for each user. When the server sends a push notification to a particular device, it sends the badge count along with the payload.
Once a device receives a push notification, iOS automatically sets the badge count on your app icon to the specified value. So this value should always be up-to-date on the server side. Remember to inform the server when a message has been read so that it can reduce the badge count. It’s a simple process:
Locally update the badge counter
Then notify the server that the information was read by sending a request
Request sent to server fails to be delivered
When a user reads new messages, the badge count on the app’s icon is updated locally and a request is sent to the server to update the badge count. This is great — unless the request fails to be delivered to the server due to a bad internet connection or some other factor. If a request fails, the server will be unaware of the status of the message and the badge count will not be updated. The next time a push arrives, the local data will not correspond to the icon count send in the push.
A developer should always guarantee the delivery of the request to the server. But how? One option would be to save the updated value of the badge counter locally, and in case of delivery failure, resend it at the next opportunity.
NOTE: Do remember that a device, not a user, subscribes for push notifications. This means that if a user logs out from an app to let somebody else log in on the same device, this device should unsubscribe from push notifications to avoid the nuisance of receiving somebody else’s pushes.
Mind user permission requests
We need access to user’s device to be able to send him notifications, but we need permission to do that.
The way your user encounters this permission request is crucial for your app, because if a user clicks “Don’t allow” just once then your app’s functionality may be severely limited.
We can explain why we need the user to subscribe for push notifications before the request for permission shows up on the screen. Our explanatory window can stress the importance of push notifications and draw attention to how an app’s functionality will be limited without them.
We can outwit the system. How? We can send a user a permission request window with options that are more appealing. For example, we might display the options “Yes” and “Later”. If a user pushes “Yes” they’ll then have to confirm that choice again by pushing “OK” in the system window. Asking two times for the same thing isn’t the best solution, but it works!
In other cases a user may push “Later.” That’s not what we want, but at least we can show the same dialog again every time they open the app until they finally press “Yes.”
There’s a great article on TechCrunch about the Cluster app’s experience with user permission requests. Check it out for insights into smart ways to handle this issue.