Search code examples
c#azurepush-notificationapple-push-notificationsazure-notificationhub

Not receiving push notification on iOS with Azure Notification Hub- didReceiveRemoteNotification is not called


I've followed these Notification Hub resources and have not been successful in receiving push notifications on my iOS device.

I've checked, rechecked, and rechecked my setup:

  1. Created a new notification hub: myhubname
  2. Followed all the certificate provisioning steps. Development Push SSL Certificate
  3. Exported the private cert and uploaded to Notification Hub under Sandbox to ensure correct APS gateway is used
  4. Downloaded the provisioning profile, which matches the bundle id for my project, auto detected for code signing, and compiles succesfully. Do NOT use the 'V2D7FJQXP.' of this string that shows up in your App ID if you are wondering: V2D7FJQXP.com.yourcompany.yourproject
  5. Running on physical device - not under simulator

A demo application that is generating push notifications:

while (true)
{
    string connectionString = ServiceBusConnectionStringBuilder.CreateUsingSharedAccessSecretWithFullAccess("myhubname-ns", "…snip");
    var hubClient = NotificationHubClient.CreateClientFromConnectionString(connectionString, "myhubname");
    var iosPayload = AppleNotificationJsonBuilder.Create("Hello!");
    iosPayload.CustomFields.Add("inAppNotification", "Hello!");
    hubClient.SendAppleNativeNotification(iosPayload.ToJsonString());

    Console.WriteLine("Sent");

    Thread.Sleep(20000);
}

No exceptions or issues are generated. Mangling any of the namespace, keys or hub names causes exceptions to be thrown, and fiddler response code from Azure is 2xx so all looks well.

I see registration occur correctly per code below:

  • I accepted push notifications on the device
  • I see the createDefaultRegistrationWithTags call once, then see that exists is true on subsequent calls.
  • No calls to didFailToRegisterForRemoteNotificationsWithError, which is OK
  • In the code example here: http://msdn.microsoft.com/library/jj927168.aspx, I have replaced sb:// with https://, as it would throw otherwise. Non-issue I'm thinking

:

-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *) deviceToken {
NSString* connectionString = [SBConnectionString stringWithEndpoint:@"https://gift-ns.servicebus.windows.net/" listenAccessSecret:@"…snip"];
self.hub = [[SBNotificationHub alloc] initWithConnectionString:connectionString notificationHubPath:@"gift-usw-dev"];
[self.hub refreshRegistrationsWithDeviceToken:deviceToken completion:^(NSError* error) {
    if (error == nil) {
        [self.hub defaultRegistrationExistsWithCompletion:^(BOOL exists, NSError* error2) {
            if (error2 == nil) {
                if (!exists) {
                    [self.hub createDefaultRegistrationWithTags:nil completion:^(NSError* error3) {
                        if (error3 != nil) {
                            NSLog(@"Error creating default registration: %@", error3);
                        }
                    }];
                }
            } else {
                NSLog(@"Error retrieving default registration: %@", error2);
            }
        }];
    } else {
        NSLog(@"Error refreshing device token: %@", error);
    }
}];
}

After starting the demo app, then running the iOS application, here is the resultant dashboard which I have no idea how to read effectively. enter image description here

Thinking that my certificates were not correct, or something was lost between Azure and APS, I dug into troubleshooting the APS service and found this: http://developer.apple.com/library/ios/#technotes/tn2265/_index.html and jumped to the section Problems Connecting to the Push Service

And ran this command:

openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert YourSSLCertAndPrivateKey.pem -debug -showcerts -CAfile server-ca-cert.pem

But I didn't have a .pem file (OSX), so I found this command to get them:

openssl pkcs12 -in keyStore.pfx -out keyStore.pem -nodes

where keyStore.pfx was the renamed version of the .p12 exported from the Keychain for the push notification cert.

The command ran fine. What is happening?


Solution

  • The AppleNotificationJsonBuilder does not serialize the payload correctly using the latest nuget of Service Bus preview features.

    So, per the examples from msdn instructions:

    var iosPayload = AppleNotificationJsonBuilder.Create("Hello!");
    iosPayload.CustomFields.Add("inAppNotification", "Hello!");
    Console.Log(iosPayload.ToJsonString());
    

    Generates:

    {"aps":{"alert":"This is a test"},"inAppNotification":Hello! This is a test}
    

    Which is malformed. Well formed is "string"

    {"aps":{"alert":"This is a test"},"inAppNotification":"Hello! This is a test"}
    

    Custom payloads are fine per http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html

    One solution is to use Json.NET, or ping someone internally at Microsoft.

    Open issues:

    • How could I have monitored network traffic off the iOS device?
    • Did the 'JSON' reach the device, but parse incorrectly? Or was it killed in the APS?
    • Azure Notification Hub dashboard did not help much

    Hopefully this saves someone their afternoon.