How to handle disabled endpoint in SNS - push-notification

I'm using AWS SNS for send a push notification to mobile app by subscribe all the device under a single SNS Topic. Then to send notification I just send to that topic.However if some endpoint could not receive a message for whatever reason, SNS will mark that endpoint as disabled.
This could be good if SNS only mark a permanent invalid endpoint, but it's not. Since if I re-enable it, then after next push notification sent its might not back to disable again which mean in the next push it can receive a message properly.
The process to re-enable was quite pain, I have to schedule a batch process to loop all the endpoint under each SNS application and re-enable each device endpoint 1 by 1. This take hours and increasing as device number grow.
How can I know which endpoint was really no longer valid due to user already uninstall an app so I don't have to bother re-enable it?
Or, is there any better way to handle this?

I believe the right solution of the problem is to stop the endpoints from getting disabled in the first place. The strategy should be such that SNS only disable the permanently invalid endpoints such as app uninstalled cases and avoid/recover from other cases.
I was in contact with the AWS support. I came to know about a case where the device token for a device can become invalid and in my case, I had a logic where I was re-enabling the endpoint of the device but using the same invalid token as before. Because of this the endpoint will become enabled but as soon as there is a push done to it, SNS will mark it disabled again since the underlying token is invalid. The right thing to do is to check if the token has changed or not from the device side and when it has pass the token for SNS registration again.
Below is the pseudo code for this strategy:
///////////////////////
retrieve the latest token from the mobile OS
if (endpoint arn not stored)
# first time registration
call CreatePlatformEndpoint
store returned endpoint arn
endif
call GetEndpointAttributes on the endpoint arn
if (getting attributes encountered NotFound exception)
#endpoint was deleted
call CreatePlatformEndpoint
store returned endpoint arn
else
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
endif
endif
//////////////////////

Related

Problem with old tokens of Huawei PUSH kit

I am using the Huawei Push Toolkit to send push messages to customers. There is a mechanism where the push tokens of each device are often refreshed, so a token used right now might be different than a token used, say, a day ago.
The issue was that if we try to send a push to a token that was valid only yesterday, the response is:
{ "code": "80000000"
"msg": "Success",
"requestId": "161615569495608835000107"
}
However, naturally, the device didn't receive the push because it was in the meantime refreshed. If sending it to the most up-to-date push token, the response is still the same and the device does get the message.
Why didn't the API return a different response, say, the error code `80300007` (all tokens invalid) in the first scenario? This is consistently replicated even for tokens older than 1 day (tested as far back as a 25 days old token).
reference
The endpoints tested were: https://push-api.cloud.huawei.com/v2/.../messages:send
and https://push-api.cloud.huawei.com/v1/.../messages:send
Both have the same behavior.
The situation you experience with the device token is normal for the Push server and it is about the information flow and the return value is just a presentation of the current node. To explain briefly 1. The Access Token is used only for the authentication interface. If the AT does not expire after the authentication succeeds, no error is reported. 2. The server pushes messages through the Push interface. If success:80000000 is returned, the Huawei Push server has received the messages, but this does not mean that the messages can be pushed to the terminal.

SNS getEndpointAttributes Returns Old Data After EventEndpointUpdated Event

When attaching a topic to a SNS application's "Endpoint updated" configurable topic I'm experiencing some unexpected behavior. Per AWS's documentation on SNS Application Events, I should receive an event on my configured topic when a platform endpoint has been updated to disabled or it's token changed.
In my case I have a lambda function subscribed to this topic that then retrieves the platform endpoint's attributes via a call to AWS's javascript sdk SNS.getEndpointAttributes so that I can check what attribute have changed to either delete the endpoint or update the associated token in my persistent storage. This call however is returning the endpoints as Enabled = true which then prevents me from taking the corrective actions. However if I look in the AWS SNS console I can see the endpoint has been disabled as Enabled = false.
Have others experienced similar inconsistencies and if so what's the best practice to get around them? Thanks for any input!
I was also facing the similar problem when amazon notified me sns application events via http. To work around this problem i actually delayed the execution of code that sync these endpoint updates with my database. To achieve this i scheduled a job for my background queue worker and delayed its execution after 30 seconds from the time amazon notified via http. I don't know whether it is a best practice or not but it is working in my scenario.

Firebase Cloud Messaging for Web - How to maintain the token list in the database and ensure they are valid or up-to-date

With Firebase Cloud Messaging for Web,
How do I maintain the list of valid tokens in my database? For example I've noticed when a user turns off notifications and revisits the site, a new token will be generated and the old token in my database is useless.
I've also tried using Firebase messaging.onTokenRefresh() callback, but it does not get called when I turned off notifications. Also in this case, even if it did get triggered, it returns a new token that was refreshed. How do I keep track of the old token that was refreshed?
Can someone please share with me their thoughts/ways to maintain and ensure the token list in the database are valid or up-to-date?
Any feedback is much appreciated.
Thank you,
Christina
messaging.onTokenRefresh() is probably a wrapper around the event onpushsubscriptionchange.
Indeed that event is currently only called when the subscription is enabled (or enabled again), but not when the permission for push notifications is revoked. So at the moment you can only know that an endpoint has expired when you try to send a notification to it.
More details:
http://blog.pushpad.xyz/2016/05/the-push-api-and-its-wild-unsubscription-mechanism/
In any case you can use the callback to send any new token to the server: at first you will have two tokens stored for the same browser, one expired and the other valid.
Some problems arise if you have data associated to the endpoint (e.g. tag) that you want to preserve during the endpoint change: see the blog post for some suggestions.

Push Notifications through Firebase

Yesterday Google has announced a new set of tools for Firebase, one of them was Notifications the ability to send notifications from server to devices which are using my app.
But can we now notify users when they receive a new message?
And if not, is there a way around to achieve this?
Looking at the documentation, this doesn't seem currently possible automatically. Here is a possible way to accomplish it "manually" with another server:
Subscribe a user to it's own user ID
In android
FirebaseMessaging.getInstance().subscribeToTopic("InsertUserIDHere");
In IOS
[[FIRMessaging messaging] subscribeToTopic:#"/topics/InsertUserIDHere"];
Setup an outside server that checks every sent messages. When a message is sent, the server should create a notification that includes the recipient's user ID as the topic.
Look here for more info.
You can send messages to group of users (targeting a specific "topic") or to a single device (targeting a Firebase Cloud Messaging token).
To subscribe a device to a topic use:
FirebaseMessaging.getInstance().subscribeToTopic("topicName");
To obtain the device token use (*1) :
FirebaseInstanceId.getInstance().getToken();
Then you can use the Firebase Notificaitons web console, or the FCM server API if you want to send messages from your server.
See: https://firebase.google.com/docs/cloud-messaging/downstream#sending_topic_messages_from_the_server
Notes:
[1] getToken() can return null if the token is not yet available.
You can use the callback onTokenRefresh() to be notified when the token is available and when the token is rotated.
See: https://firebase.google.com/docs/cloud-messaging/android/client#sample-register

APNS Push Requests are successfully sent but passes are not updating

I have an app set up to generate passbook passes. The successfully install on the device and I can do manual (pull-down) updates.
Next I began to implement APNS. I'm using the enhanced request method to connect to the production environment, sending in an empty payload (as required) and it returns no error codes when I request a push notification, but my pass never updates and I see no requests hitting my server. I'm using my own device to test until I can get see an update for myself. No pass updates are received.
I then implemented the Feedback service in the hope that it might tell me something. I noticed this. If I pass in the push token, I receive a response which indicates that the device is not receiving notifications (even though the pass is set for automatic updates). The pass is not updated.
I'd appreciate any info into why the the push notifications do not seem to be arriving.
Thanks.
-Erich
One gotcha to check is that you are not using the sandbox APNS server. All Passbook push requests should be sent to the live APNS server.
Try enabling the additional logging option from the PassKit section of the Developer Settings on your device then connecting your device to Xcode and monitoring the console as you send the push. If the push is received, then you should be able to see your device requesting the serials to be updated from your webservice and you should also see your server's response.
Assuming you send a serial and that it matches the serial installed on your device, you should then see the device requesting the updated .pkpass bundle.
If no push is received, try toggling automatic updates on and off while monitoring the device console. It could be that the device is not receiving a valid registration (201) response or that you are using a stale token - you'll be able to see these via the console.

Resources