Xamarin.forms Xamarin表单:未向ios设备接收推送通知

Xamarin.forms Xamarin表单:未向ios设备接收推送通知,xamarin.forms,xamarin.ios,firebase-cloud-messaging,Xamarin.forms,Xamarin.ios,Firebase Cloud Messaging,我做了以下几件事: 在FCM控制台中创建了一个项目,并将ios项目添加到其中 下载了GoogleService Info.plist并将其添加到xamarin forms ios项目目录中,并将构建操作设置为Bundlesource 在Info.plist上启用远程通知后台模式 在应用程序的Info.plist文件中添加了FirebaseAppDelegateProxyEnabled,并将其设置为否 创建了配置文件和分发证书,并将其安装到密钥链访问中。此外,在项目选项中映射这些证书 已在FCM控

我做了以下几件事:

  • 在FCM控制台中创建了一个项目,并将ios项目添加到其中
  • 下载了
    GoogleService Info.plist
    并将其添加到xamarin forms ios项目目录中,并将构建操作设置为
    Bundlesource
  • 在Info.plist上启用远程通知后台模式
  • 在应用程序的Info.plist文件中添加了FirebaseAppDelegateProxyEnabled,并将其设置为否
  • 创建了配置文件和分发证书,并将其安装到密钥链访问中。此外,在项目选项中映射这些证书
  • 已在FCM控制台中上载.p12证书
  • AppDelegate.cs
    中添加了处理推送通知的代码
  • 我的代码:

        [Register("AppDelegate")]
        public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate, IUNUserNotificationCenterDelegate
        {
            public override bool FinishedLaunching(UIApplication app, NSDictionary options)
            {
                global::Xamarin.Forms.Forms.Init();
                LoadApplication(new App("",""));
                RequestPushPermissionsAsync();
                _launchoptions = options;
                // Register your app for remote notifications.
            if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
            {
                // iOS 10 or later
                var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
                UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) => {
                    Console.WriteLine(granted);
                });
    
                // For iOS 10 display notification (sent via APNS)
                UNUserNotificationCenter.Current.Delegate = this;
    
                // For iOS 10 data message (sent via FCM)
                //Messaging.SharedInstance.RemoteMessageDelegate = this;
            }
            else
            {
                // iOS 9 or before
                var allNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
                var settings = UIUserNotificationSettings.GetSettingsForTypes(allNotificationTypes, null);
                UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
            }
    
            UIApplication.SharedApplication.RegisterForRemoteNotifications();
                return base.FinishedLaunching(app, options);
            }
            NSDictionary _launchoptions;
            public override void OnActivated(UIApplication uiApplication)
            {
                base.OnActivated(uiApplication);
                if (_launchoptions != null && _launchoptions.ContainsKey(UIApplication.LaunchOptionsRemoteNotificationKey))
                {
                    var notfication = _launchoptions[UIApplication.LaunchOptionsRemoteNotificationKey] as NSDictionary;
                    PresentNotification(notfication);
                }
                _launchoptions = null;
            }
    
            async Task RequestPushPermissionsAsync()
            {
                var requestResult = await UNUserNotificationCenter.Current.RequestAuthorizationAsync(
                     UNAuthorizationOptions.Alert
                    | UNAuthorizationOptions.Badge
                    | UNAuthorizationOptions.Sound);
    
                bool approved = requestResult.Item1;
                NSError error = requestResult.Item2;
                if (error == null)
                {
                    if (!approved)
                    {
                        Console.Write("Permission to receive notification was not granted");
                        return;
                    }
    
                    var currentSettings = await UNUserNotificationCenter.Current.GetNotificationSettingsAsync();
                    if (currentSettings.AuthorizationStatus != UNAuthorizationStatus.Authorized)
                    {
                        Console.WriteLine("Permissions were requested in the past but have been revoked (-Settings  app)");
                        return;
                    }
                    UIApplication.SharedApplication.RegisterForRemoteNotifications();
                }
                else
                {
                    Console.Write($"Error requesting permissions: {error}.");
                }
            }
    
            public async override void RegisteredForRemoteNotifications(
            UIApplication application, NSData deviceToken)
        {
            //if (deviceToken == null)
            //{
            //    // Can happen in rare conditions e.g. after restoring a device.
            //    return;
            //}
    
            //Console.WriteLine($"Token received: {deviceToken}");
    
            // Get current device token
            var DeviceToken = deviceToken.Description;
            if (!string.IsNullOrWhiteSpace(DeviceToken))
            {
                DeviceToken = DeviceToken.Trim('<').Trim('>');
            }
    
            Console.WriteLine($"deviceToken received: {deviceToken}");
            Console.WriteLine($"DeviceToken received: {DeviceToken}");
    
            // Get previous device token
            var oldDeviceToken = NSUserDefaults.StandardUserDefaults.StringForKey("PushDeviceToken");
    
            // Has the token changed?
            if (string.IsNullOrEmpty(oldDeviceToken) || !oldDeviceToken.Equals(DeviceToken))
            {
                //TODO: Put your own logic here to notify your server that the device token has changed/been created!
            }
    
            // Save new device token
            NSUserDefaults.StandardUserDefaults.SetString(DeviceToken, "PushDeviceToken");
    
            await SendRegistrationToServerAsync(DeviceToken);
        }
    
            async Task SendRegistrationTokenToMainPRoject(NSData deviceToken)
            {
                MessagingCenter.Send<object, string>(this, "fcmtoken", deviceToken.ToString());
            }
    
            public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
            {
                Console.WriteLine($"Failed to register for remote notifications: {error.Description}");
            }
    
            public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo,
                Action<UIBackgroundFetchResult> completionHandler)
            {
                PresentNotification(userInfo);
                completionHandler(UIBackgroundFetchResult.NoData);
                try
                {
                    UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
                    NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary;
                    var message = (aps[new NSString("webContentList")] as NSString).ToString();
                    LoadApplication(new App("", message));
                }
                catch (Exception ex)
                {
                    //LogInfo.ReportErrorInfo(ex.Message, ex.StackTrace, "AppDelegate-DidReceiveRemoteNotification");
                }
            }
    
            void PresentNotification(NSDictionary userInfo)
            {
                NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary;
    
                var msg = string.Empty;
    
                if (aps.ContainsKey(new NSString("alert")))
                {
                    msg = (aps[new NSString("alert")] as NSString).ToString();
                }
                if (string.IsNullOrEmpty(msg))
                {
                    msg = "(unable to parse)";
                }
                MessagingCenter.Send<object, string>(this, App.NotificationReceivedKey, msg);
            }
        }
    
    邮递员尸体

     {
        "to" : "d20ad003 7473bfba 85dffc33 1534decf b4b886f1 c738878f fd7f2c60 d9dabc36",
     "collapse_key" : "type_a",
     "data" : {
         "body" : "Body of Your Notification in Data",
         "title": "Title of Your Notification in Title",
         "key_1" : "Value for key_1",
         "key_2" : "Value for key_2"
     },
     "notification" : {
         "body" : "Body of Your Notification",
         "title": "Title of Your Notification",
         "sound": "default",
         "content_available" : true
     }
    }
    
    我已经完成了android部分的实现,当邮递员推送时会收到通知。但在ios部分获取
    InvalidRegistration
    错误,并且在我的ios设备中未收到任何通知

    我跟随youtube视频进行此实现,完整的源代码如下所示

    任何人都可以为这个问题提出解决方案

    提前谢谢

    更新

    {
        "multicast_id": 8754155136812875313,
        "success": 0,
        "failure": 1,
        "canonical_ids": 0,
        "results": [
            {
                "error": "InvalidRegistration"
            }
        ]
    }
    
    我已经创建了一个示例项目和一个postman集合,并将其添加到我的应用程序中

    Postman集合包含2个RESTAPI,一个用于Android设备,另一个用于ios设备

    如果导入postman集合并运行Android restapi,我将收到通知,因为我已经在上面添加了我的设备FCM令牌。但是在postman中运行ios REST API时,postman将返回
    InvalidRegistration
    error


    请浏览示例项目,并给我一个解决方案?

    我已审阅并可以解决此问题

  • 在iOS项目中安装插件Xamarin.Firebase.iOS.CloudMessaging
  • AppDelegate类需要从IUNUserNotificationCenterDelegate和IMessageDelegate接口继承
  • 包括Firebase.Core.App.Configure();在注册远程通知之前的FinishedLaunching方法中
  • 然后,您可以添加注册远程通知代码(您可以从给定的链接获取代码)
  • 您需要设置用户通知委托和消息共享即时委托(UnuseNotificationCenter.Current.delegate=this;//对于iOS 10显示通知(通过APNS发送)和消息传递.SharedInstance.delegate=this;)
  • 包括具有相应属性的DidReceiveRegistrationToken和DidReceiveMessage方法
  • 请参阅此AppDelegate类以了解更多信息

    相关Xamarin论坛线程

    我以前不使用FCM,但我想知道您是否需要在AppDelegate.cs中对firebase进行初始化?类似这样的内容:@JackHua MSFT我关注youtube视频以实现此实现,完整的源代码是。@JackHua MSFT我没有在ios部分使用任何nuget软件包,并且在视频中他没有说明firebase的初始化。@JackHua MSFT我已经用一个示例项目更新了这个问题,您能看一下吗?好的,我去看看。