我一直在关注https://docs.microsoft.com/en-gb/azure/app-service-mobile/app-service-mobile-xamarin-forms-get-started-push的教程,(向Android项目添加推送通知)

这是与服务器通信的方法:

async Task SendRegistrationToServerAsync(string token)
    {
        try
        {
            // Formats: https://firebase.google.com/docs/cloud-messaging/concept-options
            // The "notification" format will automatically displayed in the notification center if the 
            // app is not in the foreground.
            const string templateBodyFCM =
                "{" +
                    "\"notification\" : {" +
                    "\"body\" : \"$(messageParam)\"," +
                      "\"title\" : \"Xamarin University\"," +
                    "\"icon\" : \"myicon\" }" +
                "}";

            var templates = new JObject();
            templates["genericMessage"] = new JObject
            {
                {"body", templateBodyFCM}
            };

            var client = new MobileServiceClient(Organizer.App.MobileServiceUrl);
            var push = client.GetPush();

            await push.RegisterAsync(token, templates); // CRASH!!!

            // Push object contains installation ID afterwards.
            Console.WriteLine(push.InstallationId.ToString());
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Debugger.Break();
        }
    }

它在执行RegisterAsync方法时崩溃:

{Microsoft.WindowsAzure.MobileServices.MobileServiceInvalidOperationException:无法完成请求 . (未授权)在Microsoft.WindowsAzure.MobileServices.MobileServiceHttpClient d__24.MoveNext()[0x001da] in <24dbefba60fd49f4b193cdf58abf3290>:0 ---从抛出异常的上一个位置的堆栈跟踪结束---在System.Runtime.CompilerServices.TaskAwaiter .ThrowForNonSuccess(System.Threading.Tasks.Task任务)[0x0003e]位于<4d6eb5dfe2ab4eee884ef920069afd5f>中的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task任务)[0x00028]中的<4d6eb5dfe2ab4eee884ef920069afd5f>:0处于<4d6eb5dfe2ab4eee884ef920069afd5f>中的System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(System.Threading.Tasks.Task任务)[0x00008],位于<4d6eb5dfe2ab4eee884ef920069afd5f>中的System.Runtime.CompilerServices.TaskAwaiter.GetResult()[0x00000]中:0在Microsoft.WindowsAzure.MobileServices.MobileServiceHttpClient d__26.MoveNext()[0x000fc] in <24dbefba60fd49f4b193cdf58abf3290>:0 ---来自先前位置的堆栈跟踪结束,其中异常是在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks . )的<4d6eb5dfe2ab4eee884ef920069afd5f>中的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task任务)[0x0003e]抛出---任务任务)[0x00028]在<4d6eb5dfe2ab4eee884ef920069afd5f>:0中System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(System.Threading.Tasks.Task任务)[0x00008]在<4d6eb5dfe2ab4eee884ef920069afd5f>:0在System.Runtime.CompilerServices.TaskAwaiter` 1 [TResult] .GetResult()[0x00000]在<4d6eb5dfe2ab4eee884ef920069afd5f>:0中的Microsoft.WindowsAzure.MobileServices.MobileServiceHttpClient d__18.MoveNext()[0x000f0] in <24dbefba60fd49f4b193cdf58abf3290>:0 ---从上一个位置开始的堆栈跟踪异常被抛出---在System.Runtime.CompilerServices.Task的<4d6eb5dfe2ab4eee884ef920069afd5f>中的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task任务)[0x0003e]:0 Awaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task任务)[0x00028]在<4d6eb5dfe2ab4eee884ef920069afd5f>中的System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(System.Threading.Tasks.Task任务)[0x00008]中的<4d6eb5dfe2ab4eee884ef920069afd5f>中: 0中的System.Runtime.CompilerServices.TaskAwaiter.GetResult()[0x00000]在<4d6eb5dfe2ab4eee884ef920069afd5f>:0中的Organizer.Droid.MyFirebaseIIDService d _1.MoveNext()[0x00095] in /Users/mirad/mobileDevGit/OrganizerApp/Organizer.Android/ MainActivity.cs:159}

来自服务器的响应是:

{StatusCode:401,ReasonPhrase:'Unauthorized',版本:1.1,内容:System.Net.Http.StreamContent, Headers :{Transfer-Encoding:chunked Server:Microsoft-HTTPAPI / 2 . 0日期:星期五,2018年8月31日13: 21:44 GMT Content-Type:application / xml; charset = utf-8}}

需要在服务器上配置什么,以便我们不会收到401错误?

或者,还有什么可能是错的?

这是完整的MainActivity:

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    private const string TAG = "ANDROID_PUSH_NOTIFICATION";
    protected override void OnCreate(Bundle bundle)
    {

        System.Diagnostics.Debug.WriteLine("In OnCreate");
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(bundle);

        global::Xamarin.Forms.Forms.Init(this, bundle);
        LoadApplication(new App());

        if (Intent.Extras != null)
        {
            foreach (var key in Intent.Extras.KeySet())
            {
                var value = Intent.Extras.GetString(key);
                Log.Debug(TAG, "Key: {0} Value: {1}", key, value);
            }
        }

        IsPlayServicesAvailable(); 

        CreateNotificationChannel();


#if DEBUG
        // Force refresh of the token. If we redeploy the app, no new token will be sent but the old one will
        // be invalid.
        Task.Run(() =>
        {
            // This may not be executed on the main thread.
            FirebaseInstanceId.Instance.DeleteInstanceId();
            Console.WriteLine("Forced token: " + FirebaseInstanceId.Instance.Token);
        });
#endif
    }

    public bool IsPlayServicesAvailable()
    {
        int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.Success)
        {
            if (GoogleApiAvailability.Instance.IsUserResolvableError(resultCode))
            {
                // In a real project you can give the user a chance to fix the issue.
                Console.WriteLine($"Error: {GoogleApiAvailability.Instance.GetErrorString(resultCode)}");
            }
            else
            {
                Console.WriteLine("Error: Play services not supported!");
                Finish();
            }
            return false;
        }
        else
        {
            Console.WriteLine("Play Services available.");
            return true;
        }
    }

    void CreateNotificationChannel()
    {
        if (Build.VERSION.SdkInt < BuildVersionCodes.O)
        {
            // Notification channels are new in API 26 (and not a part of the
            // support library). There is no need to create a notification
            // channel on older versions of Android.
            return;
        }

        var channel = new NotificationChannel(MyFirebaseMessagingService.CHANNEL_ID,
                                              "FCM Notifications",
                                              NotificationImportance.Default)
        {

            Description = "Firebase Cloud Messages appear in this channel"
        };

        var notificationManager = (NotificationManager)GetSystemService(Android.Content.Context.NotificationService);
        notificationManager.CreateNotificationChannel(channel);
    }
}


// This service handles the device's registration with FCM.
[Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class MyFirebaseIIDService : FirebaseInstanceIdService
{

    public override void OnTokenRefresh()
    {
        var refreshedToken = FirebaseInstanceId.Instance.Token;
        Console.WriteLine($"Token received: {refreshedToken}");
        SendRegistrationToServerAsync(refreshedToken);

        //SendRegistrationTokenToAzureNotificationHub(refreshedToken);
    }



    async Task SendRegistrationToServerAsync(string token)
    {
        try
        {
            // Formats: https://firebase.google.com/docs/cloud-messaging/concept-options
            // The "notification" format will automatically displayed in the notification center if the 
            // app is not in the foreground.
            const string templateBodyFCM =
                "{" +
                    "\"notification\" : {" +
                    "\"body\" : \"$(messageParam)\"," +
                      "\"title\" : \"Xamarin University\"," +
                    "\"icon\" : \"myicon\" }" +
                "}";

            var templates = new JObject();
            templates["genericMessage"] = new JObject
            {
                {"body", templateBodyFCM}
            };

            var client = new MobileServiceClient(Organizer.App.MobileServiceUrl);
            var push = client.GetPush();

            await push.RegisterAsync(token, templates);
            //await push.RegisterAsync(token);

            // Push object contains installation ID afterwards.
            Console.WriteLine(push.InstallationId.ToString());
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Debugger.Break();
        }
    }


}

// This service is used if app is in the foreground and a message is received.
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class MyFirebaseMessagingService : FirebaseMessagingService
{
    public const string CHANNEL_ID = "MY_CHANNEL_ID";

    public override void OnMessageReceived(RemoteMessage message)
    {
        base.OnMessageReceived(message);

        Console.WriteLine("Received: " + message);

        // Android supports different message payloads. To use the code below it must be something like this (you can paste this into Azure test send window):
        // {
        //   "notification" : {
        //      "body" : "The body",
        //                 "title" : "The title",
        //                 "icon" : "myicon
        //   }
        // }
        try
        {
            var msg = message.GetNotification().Body;
            MessagingCenter.Send<object, string>(this, Organizer.App.NotificationReceivedKey, msg);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error extracting message: " + ex);
        }
    }
}

谢谢你的帮助 .