iOS/APNS 使用 Xamarin 和 Azure 应用服务移动应用的 Azure 通知中心 InvalidToken 错误
Azure Notification Hub InvalidToken error for iOS/APNS using Xamarin and Azure App Services Mobile App
我正在尝试将通知添加到我的 Azure 移动应用程序(Azure 应用程序服务移动应用程序)并且正在努力让它们与 iOS 一起工作。我已经成功地让他们为 Android.
工作
我已按照在线说明设置 Apple 证书和配置文件:
https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter5/ios/
iOS 应用正在向 APNS 注册并收到设备令牌。然后,我删除了“<”和“>”字符以及空格,并将注册发送到 Notification Hubs。
var templates = new JObject
{
["genericMessage"] = new JObject
{
{"body", "{\"aps\":{\"alert\":\"$(message)\"}}"}
}
};
var push = m_MobileServiceClient.GetPush();
await push.RegisterAsync(token, templates);
当我发送第一个推送通知请求时...
var notification = new Dictionary<string, string> { { "message", "Test notification message" } };
await m_Hub.SendTemplateNotificationAsync(notification);
...注册已从通知中心删除。
我已将 Azure 通知中心的定价层提高到标准,并使用它来查找存储帐户中存储的跟踪,它显示 "InvalidToken" 来自 APNS 的错误。
我拥有的东西done/checked:
- 作为 APNS 凭据的通知中心设置了开发证书(从 Apple 开发者门户为启用了推送通知的非通配符应用程序 ID 创建和导出)和沙盒环境。
- iOS 应用程序项目设置为使用应用程序 ID 链接到的开发者身份和配置文件:
我在 Info.plist 中添加了以下内容(并非所有说明都包含此内容,但其他文章建议它是必需的)
<key>aps-environment</key>
<string>development</string></pre>
我已尝试解决的问题
- 尝试大写 DeviceToken
- 尝试 NOT 删除空格 and/or '<' '>' 字符(这样做会产生 "InvalidTokenSize" 错误,这让我相信删除字符 是 必需的)
- 尝试更改通知中心以使用生产推送通知证书(在更改证书之间删除了中心)
我仍然继续得到 "InvalidToken"。
有没有人知道我可能做错了什么?
编辑
APNS 的 DeviceToken(删除空格和“<”“>”字符后)的长度为 64 个字符。我已经检查过,这是我在客户端中获得并发送到通知中心的内容。但是当我查看通知中心时,我得到了一个 128 个字符长的 DeviceToken。
这似乎是问题的原因。这些是我在移动端的日志(我正在输出到Outputwindow)
RegisteredForRemoteNotifications firing <7012d5d7 66e3d765 de017f65 a58e0dfb 461a6b77 9c57b6c6 60040f64 95ea20ab>
Reg with NH: 7012D5D766E3D765DE017F65A58E0DFB461A6B779C57B6C660040F6495EA20AB
但这是随后出现在设备注册中的内容(调用 https://{my_namespace}.servicebus.windows.net/{my_hub}/installations/{installationid}?api-版本=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"
]
}
}
}
我已经成功地通过使用 REST API 将安装 PUT 到客户端日志中所列的 DeviceToken 使通知正常工作。
如果我重新启动应用程序,当我重新注册到通知中心时该值会变回,因此在调用 NotificationHubClient 后某处值正在更改!
编辑 2
我已将 httpclient 流量写入输出 window,看来这是一个客户端问题,因为在调用服务器时 DeviceToken 不正确:
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)\"}}"
}
}
}
事实证明这个问题非常简单:
我是这样调用注册码的:
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);
其中 DeviceToken
的类型为 NSData
这意味着我将 string
传递给 RegisterAsync
的第一个参数,但它需要 NSData
类型。必须存在从 string
到 NSData
的隐式转换,因此它仍然编译并且 运行,但给出了错误的值。
修复是删除字符串处理并将其保留为 NSData
类型。我发现 RegisterAsync
method already does this processing for you!
我正在尝试将通知添加到我的 Azure 移动应用程序(Azure 应用程序服务移动应用程序)并且正在努力让它们与 iOS 一起工作。我已经成功地让他们为 Android.
工作我已按照在线说明设置 Apple 证书和配置文件:
https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter5/ios/
iOS 应用正在向 APNS 注册并收到设备令牌。然后,我删除了“<”和“>”字符以及空格,并将注册发送到 Notification Hubs。
var templates = new JObject
{
["genericMessage"] = new JObject
{
{"body", "{\"aps\":{\"alert\":\"$(message)\"}}"}
}
};
var push = m_MobileServiceClient.GetPush();
await push.RegisterAsync(token, templates);
当我发送第一个推送通知请求时...
var notification = new Dictionary<string, string> { { "message", "Test notification message" } };
await m_Hub.SendTemplateNotificationAsync(notification);
...注册已从通知中心删除。
我已将 Azure 通知中心的定价层提高到标准,并使用它来查找存储帐户中存储的跟踪,它显示 "InvalidToken" 来自 APNS 的错误。
我拥有的东西done/checked:
- 作为 APNS 凭据的通知中心设置了开发证书(从 Apple 开发者门户为启用了推送通知的非通配符应用程序 ID 创建和导出)和沙盒环境。
- iOS 应用程序项目设置为使用应用程序 ID 链接到的开发者身份和配置文件:
我在 Info.plist 中添加了以下内容(并非所有说明都包含此内容,但其他文章建议它是必需的)
<key>aps-environment</key> <string>development</string></pre>
我已尝试解决的问题
- 尝试大写 DeviceToken
- 尝试 NOT 删除空格 and/or '<' '>' 字符(这样做会产生 "InvalidTokenSize" 错误,这让我相信删除字符 是 必需的)
- 尝试更改通知中心以使用生产推送通知证书(在更改证书之间删除了中心)
我仍然继续得到 "InvalidToken"。
有没有人知道我可能做错了什么?
编辑
APNS 的 DeviceToken(删除空格和“<”“>”字符后)的长度为 64 个字符。我已经检查过,这是我在客户端中获得并发送到通知中心的内容。但是当我查看通知中心时,我得到了一个 128 个字符长的 DeviceToken。
这似乎是问题的原因。这些是我在移动端的日志(我正在输出到Outputwindow)
RegisteredForRemoteNotifications firing <7012d5d7 66e3d765 de017f65 a58e0dfb 461a6b77 9c57b6c6 60040f64 95ea20ab>
Reg with NH: 7012D5D766E3D765DE017F65A58E0DFB461A6B779C57B6C660040F6495EA20AB
但这是随后出现在设备注册中的内容(调用 https://{my_namespace}.servicebus.windows.net/{my_hub}/installations/{installationid}?api-版本=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"
]
}
}
}
我已经成功地通过使用 REST API 将安装 PUT 到客户端日志中所列的 DeviceToken 使通知正常工作。
如果我重新启动应用程序,当我重新注册到通知中心时该值会变回,因此在调用 NotificationHubClient 后某处值正在更改!
编辑 2
我已将 httpclient 流量写入输出 window,看来这是一个客户端问题,因为在调用服务器时 DeviceToken 不正确:
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)\"}}"
}
}
}
事实证明这个问题非常简单:
我是这样调用注册码的:
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);
其中 DeviceToken
的类型为 NSData
这意味着我将 string
传递给 RegisterAsync
的第一个参数,但它需要 NSData
类型。必须存在从 string
到 NSData
的隐式转换,因此它仍然编译并且 运行,但给出了错误的值。
修复是删除字符串处理并将其保留为 NSData
类型。我发现 RegisterAsync
method already does this processing for you!