3

We have an Azure Notification Hub set up, with APNS Configured in Production Mode, using our Production APNS Certificate. We register our test devices (using TestFlight / Production build, and certificate) to APNS, and then to ANH with a tag dealer-1. We can send notifications using our production certificate and registered Device ID with success when using APNS directly, however, when we use 'Test Send' we get a 'Successful send' to 1 device (or however many we have registered). The notification is not received. If we then run 'Test Send' again, the are 0 devices to send to.

In the logs, we see 'APNS Errors' per device, per test send. I cannot see any way to view what the errors actually are though so this is an absolutely useless metric.

I have ran through all the troubleshooting steps and confirmed many times that everything is setup in 'Production'.

Having reviewed other questions, the answers have been along the lines of:

  • .. registering a sandbox certificate and then changing it to production. Unfortunately we created this hub from scratch as Production in an attempt to work around that potential issue.
  • .. registering sandbox devices (and thus tokens) against the production certificate. Unfortunately I have controlled this closely and ensured that we are only registering TestFlight builds (thus Production) against the ANH.
  • .. uploading the wrong certificate. I have confirmed with the Push Notification Tester, as above, that the certificate is correct (thumbprint confirmed, re-uploaded, etc) and works to send to the devices via Production APNS endpoint.

The resource name is: eight-technology/react-push-notification-hub

In-app registration process is as follows:

  • Device registers for push notifications
  • Registration event is handled in iOS Project (AppDelegate event)..

    public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
    {
        //base.RegisteredForRemoteNotifications(application, deviceToken);
        App.ConfigurePushNotifications(deviceToken.ToString());
    }
    
  • ConfigurePushNotifications is in the XF Shared Project..

    public static void ConfigurePushNotifications(string deviceToken)
    {
        var azureComm = DependencyService.Get<Interop.IAzureCommunication>();
        azureComm.RegisterForPushTags(
            "sb://eight-technology.servicebus.windows.net/",
            ".. token ..",
            "react-push-notification-hub",
            deviceToken,
            StateManager.SelectedNodes.Select(m => "dealer-" + m).ToArray());
    }
    
  • The implementation is pretty much as per the sample code provided (contained in iOS project)

    public class AzureCommunication : DealerwebReact.Interop.IAzureCommunication
    {
        public void RegisterForPushTags(string url, string key, string hubName, string deviceToken, string[] tags)
        {
            var cs = SBConnectionString.CreateListenAccess(new NSUrl(url), key);
    
            var hub = new SBNotificationHub(cs, hubName);
            hub.RegisterNativeAsync(deviceToken, new NSSet(tags), err =>
            {
                if (err != null)
                    Console.WriteLine("Error: " + err.Description);
                else
                    Console.WriteLine("Success");
            });
        }
    }
    
Rudi Visser
  • 21,350
  • 5
  • 71
  • 97

3 Answers3

3

After a frustrating few days, and thanks to the help of Nikita G. and hvaughan3 I finally got to the root cause of my issue. As anticipated it wasn't any of the issues actually outlined, but was to do with the way we handled the cross-plat aspect of the registrations with Xamarin Forms.

That is, we stored our token in a class as a string. The NSData that is received as part of the iOS Device registration in RegisteredForRemoteNotifications has a ToString() method that is incompatible with sending to ANH. Furthermore, RegisterNativeAsync method from the Azure library requires an NSData which I assume Xamarin can morph a string into without warning or error, hence it was unknown that the two were somewhat incompatible.

Basically, to maintain cross platform functionality, we are now simply passing the token around as an object and performing the translation back to the original type in the platform-specific implementation of our push configuration method.

Our registration method now looks like this, note the explicit use of the NSData type so that it remains untouched whilst passing through the Xamarin Forms layer:

    public void RegisterForPushTags(string url, string key, string hubName, object deviceToken, string[] tags)
    {
        var cs = SBConnectionString.CreateListenAccess(new NSUrl(url), key);

        var hub = new SBNotificationHub(cs, hubName);
        hub.RegisterNativeAsync((NSData)deviceToken, new NSSet(tags), err =>
        {
            if (err != null)
                Console.WriteLine("Error: " + err.Description);
            else
                Console.WriteLine("Success");
        });
    }
Rudi Visser
  • 21,350
  • 5
  • 71
  • 97
1

Is this the guide you used for troubleshooting?

Is there a chance you somehow do any string (or any other type of) processing on the APN handle before you register your device? The 'APNS errors' you're seeing seem to be 'invalid token size'. Since I don't know what's going on in your code, it's hard to suggest what exactly might it be, but maybe would help you.

Nikita R.
  • 7,245
  • 3
  • 51
  • 62
  • Thanks Nikita - That was the guide I played about with yes. I'll update my post with some code, but I'm not manipulating the APN Token at all, it's passed through as an NSString straight to your classes. When I log it, it's in the format of `<... ... ...>` which I believe to be correct as that's what I can use in the APNS Tester. Do you need it changing at all? – Rudi Visser Nov 15 '16 at 11:28
  • Code provided - fairly straight forward when it comes to registration. Any ideas would be greatly appreciated. Example device token is: `<97e0614c 3c18b3d7 a8d5274b ca7037dc 3e00e703 635d5172 3c755d9c 8616f375>` – Rudi Visser Nov 15 '16 at 12:40
  • @RudiVisser Did not see your question till now. I actually do strip out the less than and greater than characters and any spaces like so: `deviceToken.ToString().Replace("<", string.Empty).Replace(">", string.Empty).Replace(" ", string.Empty);` – hvaughan3 Nov 15 '16 at 20:08
  • Yes, as @hvaughan3 said, I'm pretty sure there should not be any spaces or characters other than hex digits. Could you try without those and let us know whether it works or not? – Nikita R. Nov 15 '16 at 20:19
  • Is that Xamarin snippets? It looks like the `deviceToken.ToString()` doesn't behave the way it's supposed to. If there's another override that just returns the string without any 'special' characters then use that one. Otherwise, you'll have to do the 'hack' with replacing those manually. – Nikita R. Nov 15 '16 at 20:26
  • @NikitaG. Yes my comment's code is a Xamarin snippet. The only event in Xamarin that is triggered when the iOS app registers is the one that provides `NSData` so unfortunately the hack is needed. Android's device token comes in as a `string` which might be why the stripping is needed on iOS (as Azure needs to be able to work with multiple platforms' tokens). – hvaughan3 Nov 15 '16 at 21:34
  • @hvaughan3 lifesaver. I'll give that a try and get back to you! I found it weird that it would want that tag but just assumed it was how it was meant to be since that token format worked for APNS, and registered with Success (which doesn't seem to make sense if it fails validation). – Rudi Visser Nov 15 '16 at 22:17
  • @hvaughan3 Really thought we were on to something there, but it still didn't work with stripping it out. The 'PNS Identifier' in the Device Registrations list remained the same (ie. uppercased and without extra characters) like it was before, yet the device is still removed. Nikita are you able to check the logs again? – Rudi Visser Nov 16 '16 at 13:42
  • @RudiVisser, the stripping helped, but the token is still invalid. It looks like it's twice the length of what it should be. Is there a chance that somehow you concatenate two tokens together? – Nikita R. Nov 16 '16 at 19:16
  • @NikitaG. definitely don't do that, but I notice now that `RegisterNativeAsync` takes an NSData, so the transformation might be breaking it somehow? Is there a different method I should be using? If not, I guess I could pass the token around as an `object` so it stays in its original state. Let me give that a try now (Note I have to do this as it's x-plat). – Rudi Visser Nov 16 '16 at 21:05
  • 1
    Great success! Thanks @NikitaG. I've upvoted you, but will write a new answer describing the problem in a little more detail. I hope you guys take it under consideration to give us the actual errors rather than just stats some time, seeing 'Invalid Device Token' repeatedly could have led to this resolution much quicker :) – Rudi Visser Nov 16 '16 at 21:47
1

A similar thing happened to me when the device would register correctly but as soon as a notification was sent, the devices would disappear from the list. It always turned out to be an issue with the APNS certificate that was configured within the Notification Hub was not connected properly to the App ID and/or the app was not being signed with the correct provisioning profile.

hvaughan3
  • 10,955
  • 5
  • 56
  • 76
  • Thanks - I figured that could be a similar issue too, but then the certificate wouldn't be working directly with APNS? – Rudi Visser Nov 15 '16 at 14:43
  • @RudiVisser Right, that part of your question I was not sure about. I never did try sending notifications directly through APNS. Wish I could be more helpful on that front. Have you tried downloading and using [Service Bus Explorer](https://code.msdn.microsoft.com/windowsapps/Service-Bus-Explorer-f2abca5a)? I know it shows a little more info than the Azure site does in terms of registered devices. Have not used it recently so I cannot say if it will directly help your situation or not though. – hvaughan3 Nov 15 '16 at 15:54
  • I tried that and the app didn't work, but viewing Registered Devices in VS worked and showed the devices registered with the correct token and tag that I sent up. The whole thing is just strange & extremely frustrating :( – Rudi Visser Nov 15 '16 at 16:59