Intermittent NotificationHub delivery failures with a NotificationSystemError: "InvalidToken" - azure-notificationhub

I am running into an issue with NotificationHubs where occasionally notifications silently fail to get delivered to an iOS client.
My Notification Hub is setup to use token authentication with APNS (as opposed to the legacy certificate authentication).
I updated my notification hub pricing tier to standard so I could get some more information about it. Most of the time (over 95%) notifications go through correctly. I added logging to track the NotificationId of each push notification that was queued with Notification Hubs. Then, when I was alerted of a failure, I went and looked up the details for that specific notification via the following method:
var details = await notificationHub.GetNotificationOutcomeDetailsAsync("<notification id>");
Inspecting the details I noticed that while the State was "Completed" (meaning NotificationHubs had received and processed the operation) the PnsErrorDetailsUri had a non-null value, indicating there was an issue delivering the notification:
Navigating to the value of the PnsErrorDetailsUri in a browser caused the following file to be downloaded:
In here, I noticed that the NotificationSystemError says there was an "InvalidToken". This token seems like it should be related to some "under the covers" communication between Azure and APNS. It is definitely NOT due to the device token registered in NotificationHubs being invalid. I verified that the registrationId was still in notification hubs, and that it pointed to the correct device. In addition, grabbing the raw NotificationBody from the details and re-submitting it with the same tag causes the new notification to be delivered successfully.
Does anyone know what the InvalidToken may be referring to, or what could be the cause of these intermittent NotificationHub delivery failures?
UPDATE:
I have found mention of the different NotificationSystemErrors here, one of them being my InvalidToken error. However, I can't find a description of what the actual causes of these errors are.

I never really got a definitive answer why the error was happening, but I appear to have been able to resolve my issue.
We have 2 separate notification namespace/hub, one for apple production notifications and one for the apple sandbox notifications. We have a switch in place so devices register with the correct hub. I investigated all of our registrations, and they all looked to be in the correct location.
However, during this inspection I noticed that many devices had a large number of registrations. Each of these registrations had the SAME apple PNS identifier (which was a valid token), but it seemed odd to me that there were dozens (in one case hundreds) of the same PNS token registered. Each RegistrationID was the same, except it has a hyphenated incremented number after it (for instance, 1231231231235396312-6910179870480973035-1, 1231231231235396312-6910179870480973035-2, 1231231231235396312-6910179870480973035-3, etc.). It looks like each time I call NotificationHubClient.CreateAppleNativeRegistrationAsync, it is adding a new entry without de-duping. Clearing out these duplicate items seems to have resolved the issue I was encountering. Seems like NotificationHubs was getting confused sometimes with too many registrations being linked to a device.
I ended up adding some code on my end to attempt to filter out duplicates for the time being. However, I would expect that NotificationHubs should be handling this for me...

Related

Inconsistent notifications watching files with Google Drive REST API V3

I'm using this endpoint to subscribe for changes on a file: https://developers.google.com/drive/v3/reference/files/watch. While I'm receiving callbacks, some notifications don't happen right away and others seem to be dropped completely. I'm trying to figure out whether this is an issue with the service or something I'm not understanding about the API.
I've tried testing our setup with several different types of files and have gotten similar results with inconsistent notifications.
Wonder if anyone has done tests or has insider information about the reliability of change notifications? Is it around 99% or more like 50%? What is the expected distribution of delays? (it's definitely not instantaneous)
Without knowing what you have already done, I can only suggest that you check Push Notifications and see if you've missed some of the important things.
It was discussed that, to use push notifications, you need to do three things:
Register the domain of your receiving URL.
Set up your receiving URL, or "Webhook" callback receiver.
Set up a notification channel for each resource endpoint you want to watch.
In addition to that, note that there are required properties when making watch requests:
An id property string that uniquely identifies this new notification channel within your project. We recommend that you use a universally unique identifier (UUID) or any similar unique string.
A type property string set to the value web_hook.
An address property string set to the URL that listens and responds to notifications for this notification channel. This is your Webhook callback URL, and it must use HTTPS.
Also, Drive API will be able to send notifications to this HTTPS address only if there is a valid SSL certificate installed on your web server. Invalid certificates include:
Self-signed certificates.
Certificates signed by an untrusted source.
Certificates that have been revoked.
Certificates that have a subject that doesn't match the target hostname.
Hope that helps.

Checking for other UIRemoteNotifications waiting, inside didReceiveRemoteNotifications

In didReceiveRemoteNotification, is it possible to see if there are other/older push notifications that haven't been responded to?
I have a scenario where each notification contains different data, and unless you exit app and select every single notification for your app. You app wont be able to get to that data.
I'm thinking that iOS must be storing that information in an array somewhere, but haven't been able to find anything through Google.
Advice please? Last chance saloon would be re-writing it to poll a server for notifications.
You cannot guarantee that your app will ever receive any push notification sent to it. The only way it does is if it is running when it receives the message or if the notification is used to launch your app.
I would recommend implementing a web service on your server that allows your app to pull down the data it needs from these notifications when it is running.

How to get notified when our app is uninstalled in iOS

We are developing an iPhone application that allow users to send messages to others via Apple Push Notification Service when the target user have installed our application or SMS when haven't.
We want to get notified immediately when our app is uninstalled so that we can decide how to send the message to the target user.
We find the APNS feedback server have a long time delay that doesn't agree with our requirement. So we use another way: when our server recorded the target user have installed our application, we send him message via APNS, if he haven't read the message in 30 minutes, we believe that he has uninstalled the application, so we send the message via SMS.
Is there any way better?
As Oleg said, there is no way to accurately detect if your app was uninstalled.
The APNS feedback service returns a timestamp and a push token for messages it was not able to deliver. Sometimes, this indicates an uninstallation but it can also simply indicate a user that was simply offline at that moment. The Feedback service does have some lag so can not be used for time-sensitive intel gathering.
Based on your requirements, I'd say you're doing it right.
One suggestion that may or may not work for you would be to include a link (via url handler) to your app when you resort to sending an SMS. If it makes sense for the user to return to your app, clicking on that link should launch the app and you'll have a trace on your server if you make a simple call. If, however, after sending the SMS the user is not detected as coming back into the app, chances are highly likely that the app was indeed uninstalled or that the user is offline for an unusually long amount of time which may require some other type of action on your part.

"Push notification" - feedback, uninstall application

Apple push notification - Feedback Service
How do you know when the user uninstalls your application? so that you can remove their devicetoken from the push server.
You simply don't know. You can grab device identification string which is presumably identical for the same application token string, and track if a token has changed for the specific device. So you can update the device token with a new one, but there is no way to find out if your app was removed from a device.
Update:
You are correct. You can get this information from the feedback service, however there is a caveat. You need to have at least one push-messaging enabled application installed to maintain persistent feedback connection. I'd mark these customers as potentially non-existant, but I wouldn't remove these folks from a customer DB. Who knows why your push message can be rejected. Your device may be in inconsistent state and you remove your subscriber forever. If you have 10k zombie clients it is a pocket change for a DB. If you lost 100k clients you have much serious problems than that.

Push Notification Alternatives

I heard that push notification is not reliable. What could be the alternative for this?
The use case I am trying to handle is:
1. I have a app which will be shared by three kind of groups. Each group contains certain set of persons.
2. A request is submitted by first kind of group and it will be serviced by second kind of group. So, all persons who are part of second group should be notified and no one apart from them should get the notification.
3. Similarly, A request is submitted by first kind of group and it will be serviced by third kind of group. So, all persons who are part of third group should be notified and no one apart from them should get the notification.
4. Even second group persons can submit a request to third group.
Please provide your thoughts as how should I handle these scenarios.
Push notifications rely on the network (3G/WiFi) presence to deliver the notification. Also, there is no response back from the Apple Push Notification Server which guarantee the delivery of the notification. Having said all these things... iPod touch is higly unreliable for delivery of notification because one, it do not have 3G; second, for saving battery its notifications are internally turned off for some time....
One Alternative to this is to keep polling the server in a background thread for any modification. But this will work only when app is running.
Another Alternative can be writing our own APNS kinda infrastructure.
you're right to say Push Notifications are not reliable.
For one thing, if the device is not connected to the internet, APNs only keeps one push notification to be sent when the device connects again (the last notification sent from the provider). Since there's no way to determine if a notification has been already sent or not after your servers sent them to APNS, you can't even try to queue the notifications on your end.
Other than that if your app depends on PN the user can easily break it's functionality by turning notifications off.
So you're absolutely right, if the data you want to send is critical, then you shouldn't use Push Notification. But I believe there's really no solution to your problem. you simply can't rely on them for your app to work.
I think the best approach would be like the email app for example, where you can download your emails when you start the app wether you have PN turned on or not, and the PN just notify you of new email, even though it's not guaranteed you'll get it at all.
There is no alternative, since Apple does some very low level communication. You would need to work together with the mobile providers to build something like the notification services.
That said, I don't think the service is not reliable. Maybe you should check your implementation.
You are right that APNs does not guarantee delivery: From their docs, they say that:
Important: Because delivery is not guaranteed, you should not depend
on the remote-notifications facility for delivering critical data to
an application via the payload. And never include sensitive data in
the payload. You should use it only to notify the user that new data
is available.