I was working on my company’s mobile app albaloo which is built using Titanium SDK for Android and iPhone. As per our previous architecture whenever our user open our app, whether first time or subsequent times, we were creating Amazon SNS Endpoint based on the token received from GCM and APNS and saving the information into the database along with customer’s geo-coordinates. We were also deleting any previous endpoint created on that token from the database on that same call. We had business requirements to send push notification from our backend based on the geo-location of our customer’s devices.
To publish, we had a very simple approach first, we were selecting our desired geo-located endpoints saved in our database, subscribing them to SNS topic and publishing a notification to them. Using this approach, we have seen that push notification were not getting delivered fully to all selected endpoints. Below are the couple of issues we encountered.
1) We were not sure whether the selected endpoints are still valid or not.
2) What If the user deleted our app and we still publishes a notification to our stored endpoint ARN.
Best approach so far
So, obviously we had to change our mechanism not only for creating and storing endpoint but also how we can publish them efficiently using Amazon SNS. This approach was mentioned on Amazon Blog.
We need to be ensure about:
1) The Endpoint ARN should exist in our database as well as on SNS.
2) The app/mobile token which is used to generate an Endpoint ARN in SNS must be latest valid token.
3) The Endpoint ARN must be enabled. Amazon SNS marks an endpoint as disabled when a user removes app from his device.
Below is the pseudo code for registering an Endpoint ARN.
retrieve the latest token from the mobile OS
if (endpoint arn not stored)
# first time registration
store returned endpoint arn into the database
# subsequent times user coming to our app
get the stored endpoint arn from the database.
call GetEndpointAttributes on the endpoint arn
if (getting attributes encountered NotFound exception)
#endpoint was deleted
call CreatePlatformEndpoint again.
store returned endpoint arn
if (token in endpoint does not match latest) or
(GetEndpointAttributes shows endpoint as disabled)
call SetEndpointAttributes to set the
latest token and enable the endpoint
I have implemented this pseudo code in PHP over Here
This approach can be used anytime and the registration of the endpoint will never become invalid. Some interesting points mentioned to note about this approach:
1) We are calling SNS API CreatePlatformEndpoint twice. First is when an endpoint is not stored in our database which eventually means its a first time user. Second time, when our stored endpoint ARN doesn’t exist in Amazon SNS.
2) getEndpointAttributes is called to compare the token in Endpoint ARN with our stored token in our database. It also check if the Endpoint ARN is disabled. It will call SetEndpointAttributes to update the latest valid token if the token is not matched and mark the Endpoint ARN as enabled.
I also want to mention that sometimes even after re-installing the app on the device, It will return the same token which was previously used to generate an endpoint ARN which will create a same Endpoint ARN with disabled attribute. we were not handling this case in our first approach.
Using this approach to publish, we are determined that It will reduce the # of push notification failures and uses a latest valid token to register even If a person reinstall our app.
If you have any better approach please write down it to me.