微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 iPhone 测试设备上从 Windows PC 启动时,在 Xamarin iOS 中未获取 Firebase 云消息传递令牌 [更新]

如何解决在 iPhone 测试设备上从 Windows PC 启动时,在 Xamarin iOS 中未获取 Firebase 云消息传递令牌 [更新]

总结

我尝试使用 Firebase 云消息传递向适用于 Android 和 iOS 的 xamarin 应用发送通知。 Android 已经可以运行了。

我主要遵循此答案中的指南(以及其他几个指南):

https://stackoverflow.com/a/60001529/8542816

我收到此错误消息:

An error occurred: 'Object reference not set to an instance of an object.'. Callstack: ' at Productname.iOS.AppDelegate.FinishedLaunching (UIKit.UIApplication app,Foundation.NSDictionary options) [0x0008c] in C:\Path\repos\Productname\Productname.iOS\AppDelegate.cs:56

设置:

  • 我在 Windows PC 上进行开发,并在运行 iOS 14.4.2 的物理 iPhone 上进行调试
  • Xamarin.Firebase.iOS.CloudMessaging 4.7.1
  • Xamarin.Firebase.iOS.Core 6.10.4
  • Xamarin.Firebase.iOS.Installations 1.7.0
  • Xamarin.Firebase.iOS.InstanceID 4.8.0

我的尝试

在调试时我意识到 Messaging.SharedInstance 为空。当我搜索它时,我遇到了两种可能的解决方案:

  1. 降级到较旧的 FCM 框架(我尝试了 Xamarin.Firebase.iOS.CloudMessaging 3.1.2 和其他框架依赖项的相应降级)
  2. GoogleService-Info.plist 的问题(三重检查值,重新下载)

代码片段

GoogleService-Info.plist(设置为 BundleResource):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CLIENT_ID</key>
    <string>123456789012-replaced123456789012345678901234.apps.googleusercontent.com</string>
    <key>REVERSED_CLIENT_ID</key>
    <string>com.googleusercontent.apps.123456789012-replaced123456789012345678901234</string>
    <key>API_KEY</key>
    <string>HereIsThe_KeyWhichIReplaced123456789012</string>
    <key>GCM_SENDER_ID</key>
    <string>123456789012</string>
    <key>PLIST_VERSION</key>
    <string>1</string>
    <key>BUNDLE_ID</key>
    <string>de.companyname.productname</string>
    <key>PROJECT_ID</key>
    <string>productname-a43fc</string>
    <key>STORAGE_BUCKET</key>
    <string>productname-a43fc.appspot.com</string>
    <key>IS_ADS_ENABLED</key>
    <false></false>
    <key>IS_ANALYTICS_ENABLED</key>
    <false></false>
    <key>IS_APPINVITE_ENABLED</key>
    <true></true>
    <key>IS_GCM_ENABLED</key>
    <true></true>
    <key>IS_SIGNIN_ENABLED</key>
    <true></true>
    <key>GOOGLE_APP_ID</key>
    <string>1:123456789012:ios:0123456789abcdef012345</string>
    <key>DATABASE_URL</key>
    <string>https://productname-a43fc.firebaseio.com</string>
</dict>
</plist>

AppDelegate.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using Firebase.InstanceID;
using Firebase.Core;
using Firebase.CloudMessaging;
using Foundation;
using Productname.Models.Global;
using UIKit;
using UserNotifications;

namespace Productname.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate,IMessagingDelegate,IUNUserNotificationCenterDelegate
    {
        public override bool FinishedLaunching(UIApplication app,NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());
            // Register your app for remote notifications.
            if (UIDevice.CurrentDevice.CheckSystemVersion(10,0))
            {

                // For iOS 10 display notification (sent via APNS)
                UNUserNotificationCenter.Current.Delegate = (IUNUserNotificationCenterDelegate)this;

                var authOptions = UNAuthorizationoptions.Alert | UNAuthorizationoptions.Badge | UNAuthorizationoptions.sound;
                UNUserNotificationCenter.Current.RequestAuthorization(authOptions,(granted,error) => {
                    Console.WriteLine(granted);
                });
            }
            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();

            Firebase.Core.App.Configure();

            Messaging.SharedInstance.Delegate = this; // <-- The Execution crashes here

            InstanceId.SharedInstance.GetInstanceId(InstanceIdResultHandler);

            return base.FinishedLaunching(app,options);
        }

        [Export("messaging:didReceiveRegistrationToken:")]
        public void DidReceiveRegistrationToken(Messaging messaging,string fcmToken)
        {
            //Never Fired
            Firebasetoken.Singleton.Token = fcmToken;
            Console.WriteLine($"Firebase registration token: {fcmToken}");
            Loginformation(nameof(DidReceiveRegistrationToken),$"Firebase registration token: {fcmToken}");
        }


        void InstanceIdResultHandler(InstanceIdResult result,NSError error)
        {
            if (error != null)
            {
                Loginformation(nameof(InstanceIdResultHandler),$"Error: {error.LocalizedDescription}");
                return;
            }

            Loginformation(nameof(InstanceIdResultHandler),$"Remote Instance Id token: {result.Token}");
        }

        public override void DidReceiveRemoteNotification(UIApplication application,NSDictionary userInfo,Action<UIBackgroundFetchResult> completionHandler)
        {
            HandleMessage(userInfo);

            // Print full message.
            Loginformation(nameof(DidReceiveRemoteNotification),userInfo);

            completionHandler(UIBackgroundFetchResult.NewData);
        }

        [Export("messaging:didReceiveMessage:")]
        public void DidReceiveMessage(Messaging messaging,RemoteMessage remoteMessage)
        {
            // Handle Data messages for iOS 10 and above.
            HandleMessage(remoteMessage.AppData);

            Loginformation(nameof(DidReceiveMessage),remoteMessage.AppData);
        }

        void HandleMessage(NSDictionary message)
        {
        }

        public static void ShowMessage(string title,string message,UIViewController fromViewController,Action actionForOk = null)
        {
            var alert = UIAlertController.Create(title,message,UIAlertControllerStyle.Alert);
            alert.AddAction(UIAlertAction.Create("Ok",UIAlertActionStyle.Default,(obj) => actionForOk?.Invoke()));
            fromViewController.PresentViewController(alert,true,null);
        }

        void Loginformation(string methodName,object information) => Console.WriteLine($"\nMethod name: {methodName}\ninformation: {information}");
    }
}

Info.plist 中的远程通知已激活。

当我注释掉 Messaging.SharedInstance.Delegate = this; 行时,除了缺少通知功能之外,应用程序将启动并完美运行。

非常感谢任何提示或进一步的调试方法

更新

我设法拿到了 MacBook。我在同一台测试 iPhone 设备上通过 Visual Studio 从 MacBook 启动了该应用程序,它立即运行。不过,我想在我的 Windows PC 上保留开发和测试过程。甚至有可能吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。