Reputation: 2178
I'm trying to add Notifications to my Azure Mobile App (Azure App Services Mobile App) and am struggling to get them working with iOS. I have successfully got them working for Android.
I've followed instructions online to set up the Apple certificates and provisioning profiles:
https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter5/ios/
The iOS app is registering with APNS and a Device Token received. I then remove the '<' and '>' characters, and the spaces, and sent the registration to Notification Hubs.
var templates = new JObject
{
["genericMessage"] = new JObject
{
{"body", "{\"aps\":{\"alert\":\"$(message)\"}}"}
}
};
var push = m_MobileServiceClient.GetPush();
await push.RegisterAsync(token, templates);
When I send the first request for a Push Notification...
var notification = new Dictionary<string, string> { { "message", "Test notification message" } };
await m_Hub.SendTemplateNotificationAsync(notification);
...the registration is removed from Notification Hubs.
I've upped the pricing tier on the Azure Notification Hub to Standard and used that to look up the tracking stored in the storage account and it shows "InvalidToken" as the error from the APNS.
Things I have done/checked:
I added the following into the Info.plist (not all instructions included this but other articles suggested it was required)
<key>aps-environment</key>
<string>development</string>
Things I have tried to fix it
Still I continue to get "InvalidToken".
Does anyone have any ideas what I might be doing wrong?
EDIT
The DeviceToken for APNS (after removing spaces and '<' '>' characters) is 64 characters long. I have checked and this is what I get in the client and send to the notification hub. But when I look in the notification hub I am getting a DeviceToken that is 128 characters long.
This appears to be the cause of the issue. These are my logs on the mobile side (I am outputting to the Output window)
RegisteredForRemoteNotifications firing <7012d5d7 66e3d765 de017f65 a58e0dfb 461a6b77 9c57b6c6 60040f64 95ea20ab>
Reg with NH: 7012D5D766E3D765DE017F65A58E0DFB461A6B779C57B6C660040F6495EA20AB
but this is what then appears in the Device Registration (calling https://{my_namespace}.servicebus.windows.net/{my_hub}/installations/{installationid}?api-version=2015-01
{
"installationId": "{installationId}",
"pushChannel": "37303132443544373636453344373635444530313746363541353845304446423436314136423737394335374236433636303034304636343935454132304142",
"pushChannelExpired": false,
"platform": "apns",
"expirationTime": "9999-12-31T23:59:59.9999999Z",
"tags": [
...
],
"templates": {
"genericMessage": {
"body": "{\"aps\":{\"alert\":\"$(message)\"}}",
"tags": [
"genericMessage"
]
}
}
}
I've managed to get the Notification working successfully by using the REST API to PUT the Installation to have the DeviceToken as listed in the client-side logs.
If I restart the App, the value changes back when I re-register with the Notification Hub, so somewhere after calling the NotificationHubClient the value is being changed!
EDIT 2
I've written the httpclient traffic to the output window, at it appears that this is a client-side issue as the DeviceToken is incorrect when the call is made to the server:
Method: PUT,
RequestUri: 'https://{my_namespace}/push/installations/5ed26cac-2735-4d58-91f4-2220569a3f0c',
Version: 1.1,
Content: System.Net.Http.StringContent,
Headers:
{
X-ZUMO-INSTALLATION-ID: 5ed26cac-2735-4d58-91f4-2220569a3f0c
X-ZUMO-AUTH: ...
Accept: application/json
User-Agent: ZUMO/3.1 (lang=Managed; os=iOS; os_version=10.3.2; arch=MacOSX; version=3.1.50105.0)
X-ZUMO-VERSION: ZUMO/3.1 (lang=Managed; os=iOS; os_version=10.3.2; arch=MacOSX; version=3.1.50105.0)
ZUMO-API-VERSION: 2.0.0
Content-Type: application/json; charset=utf-8
}
{
"pushChannel": "37303132443544373636453344373635444530313746363541353845304446423436314136423737394335374236433636303034304636343935454132304142",
"platform": "apns",
"templates": {
"genericMessage": {
"body": "{\"aps\":{\"alert\":\"$(message)\"}}"
}
}
}
Upvotes: 1
Views: 1627
Reputation: 2178
The issue turned out to be annoyingly simple:
I was calling the registration code like this:
var token = DeviceToken.Description.Trim('<', '>').Replace(" ", "").ToUpperInvariant();
var templates = new JObject
{
["genericMessage"] = new JObject
{
{"body", "{\"aps\":{\"alert\":\"$(message)\"}}"}
}
};
var push = m_MobileServiceClient.GetPush();
await push.RegisterAsync(token, templates);
Where DeviceToken
is of type NSData
This meant I was passing a string
into the first parameter of RegisterAsync
but it requires an NSData
type. There must be an implicit cast from string
to NSData
so it still compiled and ran, but gave the wrong value.
The fix was to remove the string processing and leave it as an NSData
type. I turns out that the RegisterAsync
method already does this processing for you!
Upvotes: 5