如何解决在 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
为空。当我搜索它时,我遇到了两种可能的解决方案:
- 降级到较旧的 FCM 框架(我尝试了 Xamarin.Firebase.iOS.CloudMessaging 3.1.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 举报,一经查实,本站将立刻删除。