我找不到任何有关如何在毛伊岛实现推送通知的文档。也许有人能够将 xamarin 库集成到 maui 项目中来完成它?
.NET MAUI 仍处于预览阶段,因此虽然“踢轮胎”经常发生,但没有人应该在生产中实际使用它。比特以及文档和第三方库仍在进行中。
话虽如此,推送通知之类的概念实际上不会发生太大变化。推送通知仍然经常发生在特定于平台的层上。例如,如果您遵循 this 指南,您会看到它提到了适用于 Android 的
MainActivity
,尽管位于不同的位置,但它仍然存在。 iOS 中的 AppDelegate
也是如此。
您必须将一些概念转换为 .NET MAUI,但弄清楚它不应该太复杂。但如果您不能并且有时间,请再等一会儿,库和文档会赶上!
希望下面的教程将帮助您在 iOS 平台上启用 Firebase Cloud Messaging for .NET MAUI 项目。
我认为您已正确设置 Apple 配置文件。这意味着您在 Apple 开发者网站上设置了 Certificate、Identifier 和 Profile(尤其是 Distribution - App Store)。不要忘记在应用程序的标识符页面上启用“推送通知”,并使用与您在应用程序中使用的相同的捆绑包ID。在 Keys 页面 配置 APN Key - 选中“Apple 推送通知服务 (APNs)” - 下载并记住 Key ID。您将在 Firebase 控制台中需要它。
我还认为 Firebase Console 上的所有准备工作都是根据 tutorial 完成的,并且您已准备好 GoogleService-Info.plist 文件(但未添加到您的项目中)。不要忘记在页面项目设置,选项卡“云消息”,“Apple 应用程序配置”部分注册APNs身份验证密钥。
项目变更Visual Studio 2022 中使用 MAUI 项目打开解决方案。在我的例子中,版本为 17.3.6,.NET SDK 6.0.402,MAUI 工作负载 6.0.541,使用 Xcode 14.0.1 构建服务器 macOS Monterey 12.6。
检查项目属性中的“目标 iOS 框架”设置为“net6.0-ios15.4”,然后使用Nuget Package Manager 以传统方式添加 nuget 包“Xamarin.Firebase.iOS.CloudMessaging”版本 8.10.0.2。
您可能会遇到很长的问题。包安装可能会失败并出现异常 “System.IO.DirectoryNotFoundException:找不到路径 'C:\Users\...\.nuget\packages\xamarin.firebase.ios.installations\...\FirebaseInstallations-umbrella.h' 的一部分。” 但是您可以通过将Nuget.config 文件添加到解决方案文件夹中来解决此问题:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<clear />
<add key="globalPackagesFolder" value="C:\Nuget" />
</config>
</configuration>
将 Entitlements.plist 文件添加到 Platforms\iOS 文件夹中,内容如下:
<?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>aps-environment</key>
<string>development</string>
</dict>
</plist>
添加到 Info.plist 文件中这些行:
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
</array>
您可以通过将以下行添加到项目文件中来包含生成的 GoogleService-Info.plist:
<ItemGroup Condition="'$(TargetFramework)'=='net6.0-ios15.4'">
<BundleResource Include="Platforms\iOS\GoogleService-Info.plist" />
</ItemGroup>
...并让 Firebase 包从中读取设置,但让我们保持简单,不要将此文件添加到项目中。相反,更改文件 Platforms\iOS\
AppDelegate.cs,如下所示:
using Firebase.CloudMessaging;
using Foundation;
using UIKit;
using UserNotifications;
namespace ...
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate, IUNUserNotificationCenterDelegate, IMessagingDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
...
var result = base.FinishedLaunching(application, launchOptions);
var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) =>
{
this.Log($"RequestAuthorization: {granted}" + (error != null ? $" with error: {error.LocalizedDescription}" : string.Empty));
if (granted && error == null)
{
this.InvokeOnMainThread(() =>
{
UIApplication.SharedApplication.RegisterForRemoteNotifications();
this.InitFirebase();
});
}
});
return result;
}
private void InitFirebase()
{
this.Log($"{nameof(this.InitFirebase)}");
try
{
var options = new Firebase.Core.Options("[GOOGLE_APP_ID]", "[GCM_SENDER_ID]");
options.ApiKey = "[API_KEY]";
options.ProjectId = "[PROJECT_ID]";
options.BundleId = "[BUNDLE_ID]";
options.ClientId = "[CLIENT_ID]";
Firebase.Core.App.Configure(options);
}
catch (Exception x)
{
this.Log("Firebase-configure Exception: " + x.Message);
}
UNUserNotificationCenter.Current.Delegate = this;
if (Messaging.SharedInstance != null)
{
Messaging.SharedInstance.Delegate = this;
this.Log("Messaging.SharedInstance SET");
}
else
{
this.Log("Messaging.SharedInstance IS NULL");
}
}
// indicates that a call to RegisterForRemoteNotifications() failed
// see developer.apple.com/documentation/uikit/uiapplicationdelegate/1622962-application
[Export("application:didFailToRegisterForRemoteNotificationsWithError:")]
public void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
{
this.Log($"{nameof(FailedToRegisterForRemoteNotifications)}: {error?.LocalizedDescription}");
}
// this callback is called at each app startup
// it can be called two times:
// 1. with old token
// 2. with new token
// this callback is called whenever a new token is generated during app run
[Export("messaging:didReceiveRegistrationToken:")]
public void DidReceiveRegistrationToken(Messaging messaging, string fcmToken)
{
this.Log($"{nameof(DidReceiveRegistrationToken)} - Firebase token: {fcmToken}");
//Utils.RefreshCloudMessagingToken(fcmToken);
}
// the message just arrived and will be presented to user
[Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
var userInfo = notification.Request.Content.UserInfo;
this.Log($"{nameof(WillPresentNotification)}: " + userInfo);
// tell the system to display the notification in a standard way
// or use None to say app handled the notification locally
completionHandler(UNNotificationPresentationOptions.Alert);
}
// user clicked at presented notification
[Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")]
public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
{
this.Log($"{nameof(DidReceiveNotificationResponse)}: " + response.Notification.Request.Content.UserInfo);
completionHandler();
}
void Log(string msg)
{
...
}
}
...并更改 Options
值以更正GoogleService-Info.plist 文件中的值... 构建和测试
请注意,Firebase iOS CloudMessaging
仅在发布模式下工作。在调试模式下,无论您使用正确设置的手动配置在物理设备上进行测试,Configure
方法都会失败,并显示消息“无法创建“Firebase.Core.Options”类型的本机实例:本机类尚未加载”轮廓。因此,我们可以仅使用TestFlight 或 AdHoc 分发来测试消息传递。 发送测试通知消息的最简单方法是使用
Firebase Console。只需打开 Engage 菜单中的 Cloud Messaging 项目,然后点击“发送您的第一条消息”按钮。填写“通知文本”字段并点击“发送测试消息”,在“添加 FCM 注册令牌”字段中填写令牌(您从 iOS 应用程序的日志文件中获取它),然后点击“测试”按钮。
推荐链接