Google Cloud Platform Blog
Product updates, customer stories, and tips and tricks on Google Cloud Platform
Google App Engine takes the pain out of sending iOS push notifications
Monday, July 1, 2013
Delivering scalable, reliable mobile push notifications when hundreds of thousands of users have installed your app on their phones can be a major headache. Fortunately, Google App Engine’s support for sockets and accessible but powerful queues makes it easy to quickly build a mobile backend that can reliably scale to huge numbers of devices.
Get the code!
We’ve created a simple push notification application to help you get started in our Github repository that uses all of the techniques described below.
Download or fork the source
code to get started.
Push notifications are the little pings your phone gives you to let you know that you’ve got a new message, your friend is waiting for you to take your turn on the latest game or that band you like has just announced a concert in your town. As a developer, push notifications give you a new dimension to engage with your users in real time, any time, regardless as whether they have your app open or even if they have their phone in their hand.
On iOS devices, like iPhones and iPads, push notifications are handled by Apple’s Push Notification Service (APNS). APNS is hosted by Apple, and acts as a bridge between your server and your mobile clients. In brief, here’s how it works:
Your mobile application securely registers itself with Apple to be able to receive push notifications, usually when the app is being launched the first time. It receives a device token, which the mobile application passes to your mobile backend.
Your server opens a secure connection to APNS, and when an event occurs that requires a push notification - your server sends a short message including the device token of the device that should receive the message to APNS. APNS will then handle the ‘last-mile delivery’ of the notification to the device.
Although this seems relatively trivial, there are a few important things to consider when implementing push notifications in your application.
Connection pooling with backend instances and pull queues
If you have a popular application you can quickly end up generating a large number of push notifications - even after a single event.
For both performance reasons, and should avoid opening a large number of secure connections to APNS, but rather simply hold a few connections open and funnel any push notifications your applications generate through those. This approach is commonly called Connection Pooling.
Fortunately, App Engine provides the building blocks for scalable connection pooling. Resident
backend instances
are long running App Engine containers that can be used to as workers to hold open APNS notifications for sending notifications. These workers can then
monitor a pull queue
that can signal to the workers when a notification should be sent. When an event occurs in another component of your application that should trigger a push notification (say an action triggered by your mobile API in a frontend instance), other components of your application can simply enqueue a task on the pull queue.
Each worker can then periodically read from a pull queue to see if any notifications need to be sent by the application, and if there are, lease a block of them, send them via the previously established APNS connection, and delete them.
As well as saving on opening many connections to APNS, this approach also improves the reliability of the app. If a worker is unable to deliver a message to APNS for some reason (e.g., because the TCP connection was severed), App Engine’s pull queues will release the lease on the task and allow another worker to retry it. You can also scale the solution simply by adding additional workers that read off the same pull queue.
Sending bulk notifications with push queues and cursors
You may find a need to send a push notification to a large number of devices at once. This requires a query to your database/datastore to find the list of relevant device tokens and then enqueuing a request onto the pull queue described above that includes the message you want to send along with the relevant device token.
If you were to attempt this in a single request, you could quickly run into problems as your list of device IDs becomes large. A simple but elegant solution is to use push queues and (if you’re storing device IDs in the App Engine datastore) query cursors.
A
query cursor
is a token that can be used to iterate over a given a given query result set in small batches. A query cursor is an opaque string marking the index position of the last result retrieved. The application can then use the cursor as the starting point for a subsequent retrieval operation, to obtain the next batch of results from the point where the previous retrieval ended
Query cursors can be combined with App Engine push queues. A
push queue
handler is written to take a query and an optional cursor. The push queue handler then executes the query with a small result limit (say 100 entities), and for each result adds a task to the pull queue described above. If the result of the query also includes a cursor then this indicates there are still unretrieved entities in the query. Once the task handler has cycled through the results it has retrieved, if it has a new cursor, then it can initiate a new push task with that cursor’s value.
Connecting to APNS
While you can use App Engine’s outbound sockets support to talk to APNS from
Java
or
Python
directly, popular 3rd party libraries such as
JavaPNS
also work well, and often provide a cleaner higher level interface for sending notifications.
Putting it all together
Although this sounds like a lot, putting all of this together on App Engine is remarkably straightforward, requiring only a simple batch query queue handler and notification worker. Everything else is taken care of by App Engine’s robust queueing and datatore APIs.
If you’re feeling ready to add Push Notifications to your app, we’ve got some great resources to help you get started.
Download the source
to our (Java) iOS push notification example on Github
Read our in depth Cloud solutions paper
on Orchestrating iOS Push Notifications, which covers this architecture (and more) in greater detail
Read more about push queues (
Python
,
Java
), pull queues (
Python
,
Java
) and outbound sockets (
Python
,
Java
)
- Posted by Grzegorz Gogolowicz, Solutions Architect
Free Trial
GCP Blogs
Big Data & Machine Learning
Kubernetes
GCP Japan Blog
Firebase Blog
Apigee Blog
Popular Posts
Understanding Cloud Pricing
World's largest event dataset now publicly available in BigQuery
A look inside Google’s Data Center Networks
New in Google Cloud Storage: auto-delete, regional buckets and faster uploads
Getting your data on, and off, of Google App Engine
Labels
Announcements
193
Big Data & Machine Learning
134
Compute
271
Containers & Kubernetes
92
CRE
27
Customers
107
Developer Tools & Insights
151
Events
38
Infrastructure
44
Management Tools
87
Networking
43
Open
1
Open Source
135
Partners
102
Pricing
28
Security & Identity
85
Solutions
24
Stackdriver
24
Storage & Databases
164
Weekly Roundups
20
Feed
Subscribe by email
Demonstrate your proficiency to design, build and manage solutions on Google Cloud Platform.
Learn More
Technical questions? Check us out on
Stack Overflow
.
Subscribe to
our monthly newsletter
.
Google
on
Follow @googlecloud
Follow
Follow