如果应用服务使用身份验证,Azure 通知中心设备注册失败

Azure Notification Hub Device Registration Fails if App Service Uses Authentication

我有一个正在运行的 Azure 应用服务连接到配置了 GCM 和 APNS 的通知中心。它已经在两个平台上完美运行了几个月。

我现在已经在应用程序服务中打开身份验证并配置了 google 和 facebook。这些也很完美,正确的访问是对简单表的尊重。

但是,由于启用了身份验证,现在无法从移动应用程序注册设备。

以下是我在应用服务(NodeJS)上遇到的错误:

System.NullReferenceException: Object reference not set to an instance of an object.
  at Microsoft.Azure.AppService.Push.PushRequestHandler.<HandleCreateOrUpdateInstallationAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
 at  System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.AppService.Push.PushRequestHandler.<HandlePushRequestAsync>d__f.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.AppService.Push.PushModule.<OnPostAuthenticateRequestAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.AppService.Authentication.HttpModuleDispatcher.<DispatchAsync>d__13.MoveNext()
2016-11-14T09:43:00  PID[7348] Information Sending response: 500.79 Internal Server Error
2016-11-14T09:43:00  PID[7348] Critical    System.ComponentModel.Win32Exception (0x80004005): An operation was attempted on a nonexistent network connection
at CHttpRequest.ReadEntityBody(Byte[] buffer, Int32 maxLength, Boolean allowAsync, Int32& bytesReceived, Int32& bytesRemaining, Boolean& completionPending)
at Microsoft.Azure.AppService.Authentication.HttpRequestBase.AsyncReadHelper.Read()
at Microsoft.Azure.AppService.Authentication.HttpRequestBase.AsyncReadHelper..ctor(HttpRequestBase request, Int32 maxLength)
at Microsoft.Azure.AppService.Authentication.HttpRequestBase.<ReadRequestContentAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.AppService.Push.PushRequestHandler.<HandleCreateOrUpdateInstallationAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.AppService.Push.PushRequestHandler.<HandlePushRequestAsync>d__f.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.AppService.Push.PushModule.<OnPostAuthenticateRequestAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.AppService.Authentication.HttpModuleDispatcher.<DispatchAsync>d__13.MoveNext()
2016-11-14T09:43:00  PID[7348] Information Sending response: 500.79 Internal Server Error

我可以向现有注册发送通知(使用测试发送和通过我的服务器推送代码),我只是无法创建新注册。

当我关闭身份验证后,一切又恢复正常了。

在此身份验证方案中,我是否需要在通知中心手动创建注册?

我不知道哪里出了问题,所以非常感谢您的帮助。

这是推送的问题blade,不是你自己能解决的。我已通过电子邮件与您联系,以便我们可以直接为您提供支持。

作为导致问题的 RegisterAsync 的替代方法;您可以使用 HttpClient 调用来 PUT 通知中心安装。以下代码将在 Android 上设置安装,例如:

public async Task RegisterForPushNotifications(MobileServiceClient client)
{
    if (GcmClient.IsRegistered(RootView))
    {
        try
        {
            var registrationId = GcmClient.GetRegistrationId(RootView);
            //var push = client.GetPush();
            //await push.RegisterAsync(registrationId);

            var installation = new DeviceInstallation
            {
                InstallationId = client.InstallationId,
                Platform = "gcm",
                PushChannel = registrationId
            };
            // Set up tags to request
            installation.Tags.Add("topic:Sports");
            // Set up templates to request
            PushTemplate genericTemplate = new PushTemplate
            {
                Body = "{\"data\":{\"message\":\"$(messageParam)\"}}"
            };
            // Register with NH
            var response = await client.InvokeApiAsync<DeviceInstallation, DeviceInstallation>(
                $"/push/installations/{client.InstallationId}",
                installation,
                HttpMethod.Put,
                new Dictionary<string, string>());
        }
        catch (Exception ex)
        {
            Log.Error("DroidPlatformProvider", $"Could not register with NH: {ex.Message}");
        }
    }
    else
    {
        Log.Error("DroidPlatformProvider", $"Not registered with GCM");
    }
}

DeviceInstallation class 看起来像这样:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace TaskList.Abstractions
{
    public class DeviceInstallation
    {
        public DeviceInstallation()
        {
            Tags = new List<string>();
            Templates = new Dictionary<string, PushTemplate>();
        }

        [JsonProperty(PropertyName = "installationId")]
        public string InstallationId { get; set; }

        [JsonProperty(PropertyName = "platform")]
        public string Platform { get; set; }

        [JsonProperty(PropertyName = "pushChannel")]
        public string PushChannel { get; set; }

        [JsonProperty(PropertyName = "tags")]
        public List<string> Tags { get; set; }

        [JsonProperty(PropertyName = "templates")]
        public Dictionary<string, PushTemplate> Templates { get; set; }
    }

    public class PushTemplate
    {
        public PushTemplate()
        {
            Tags = new List<string>();
            Headers = new Dictionary<string, string>();
        }

        [JsonProperty(PropertyName = "body")]
        public string Body { get; set; }

        [JsonProperty(PropertyName = "tags")]
        public List<string> Tags { get; set; }

        [JsonProperty(PropertyName = "headers")]
        public Dictionary<string, string> Headers { get; set; }
    }
}

将 RegisterForPushNotifications() 方法放在特定于平台的代码中。 DeviceInstallation 可以在 PCL.

不确定您是否在使用 Xamarin.Forms,但我已经为此苦苦挣扎了一个半星期。

发现: