mcpField
M
maui-push-notifications

maui-push-notifications

github.com/davidortinau开发17646 次安装16 周前更新
代码仓库

关于 maui-push-notifications

这项 .NET MAUI 技能介绍 Android 和 iOS 推送通知的实现与故障排查,提供平台检查清单,并说明令牌注册、权限、通知渠道及 Azure Notification Hub 的限制。

主要功能

  1. 01说明令牌刷新与重新注册
  2. 02涵盖 Android 通知权限和渠道
  3. 03列出 iOS APNs 配置要求
  4. 04说明平台注册值
  5. 05介绍 Azure Notification Hub 标签限制
  6. 06提供 Android、iOS 和后端检查清单

适用场景

  1. 01排查 Android 通知未送达
  2. 02调试令牌注册与刷新问题
  3. 03为实体设备准备 iOS 推送配置
  4. 04避免 Azure Notification Hub 标签限制错误

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/davidortinau/maui-skills --skill maui-push-notifications

安装后在 Claude Code 中输入/maui-push-notifications确认已加载。

附带文件references/push-notifications-api.md

详细介绍

推送通知 — 注意事项与最佳实践

故障排查表

问题原因解决方法
每次调试运行时令牌都会变化(Android)调试构建会重新生成 Firebase 令牌始终在 OnNewToken 中重新注册
HttpClient 请求静默失败BaseAddress 末尾缺少 /确保端点以 / 结尾
iOS 推送无法送达模拟器模拟器不支持 APNS使用实体 iOS 设备
Android 13+ 上没有通知需要 POST_NOTIFICATIONS(API 33+)在 OnCreate 中调用 RequestPermissions
缺少通知渠道(API 26+)Android 要求显式创建渠道发送前创建渠道
SendNotificationAsync 因标签超过 20 个而抛出异常Azure NH 标签表达式限制将标签分成每组 20 个进行批处理
设备注册时出现 422平台字符串不匹配使用 "fcmv1"(而非 "gcm")和 "apns"
RegisterAsync 时令牌为空冷启动时发生竞态条件使用 IsNullOrWhiteSpace 检查进行保护

关键注意事项

⚠️ BaseAddress 末尾必须有斜杠

HttpClient.BaseAddress 必须以 / 结尾。否则,相对 URI 解析会静默失效。

// ❌ Relative URIs resolve incorrectly
_http = new HttpClient { BaseAddress = new Uri("https://example.com") };

// ✅ Trailing slash required
_http = new HttpClient { BaseAddress = new Uri("https://example.com/") };
⚠️ Android:令牌刷新时始终重新注册

Firebase 令牌在调试构建中会频繁重新生成。如果跳过 OnNewToken,后端就会保留过期令牌,导致推送静默失败。

// ❌ Only registering once at startup
// (token may change later without re-registration)

// ✅ Always re-register in OnNewToken
public override void OnNewToken(string token)
{
    var svc = IPlatformApplication.Current?.Services.GetService<IPushNotificationService>();
    if (svc is null) return;
    svc.Token = token;
    _ = svc.RegisterAsync();
}
⚠️ Android 13+ 需要 POST_NOTIFICATIONS 权限

在 API 33+ 上,如果不显式请求 POST_NOTIFICATIONS,通知会被静默丢弃。

⚠️ Azure NH 标签表达式限制:20 个标签

如果标签表达式引用的标签超过 20 个,SendNotificationAsync 就会抛出异常。请分批处理:

// ✅ Batch tags to stay under the limit
var batches = request.Tags.Chunk(20);
foreach (var batch in batches)
{
    var tagExpr = string.Join(" || ", batch);
    await _hub.SendFcmV1NativeNotificationAsync(payload, tagExpr, ct);
}
⚠️ 使用 "fcmv1",而非 "gcm"

旧版 "gcm" 平台字符串会导致设备注册时出现 422 错误。Android 始终使用 "fcmv1",iOS 使用 "apns"。

⚠️ iOS 模拟器无法接收推送通知

APNS 仅适用于实体 iOS 设备。模拟器会静默忽略推送注册。

平台检查清单

Android
  • 将 google-services.json 放在 Platforms/Android/ 中,并在 .csproj 中配置 <GoogleServicesJson>
  • 添加 Xamarin.Firebase.Messaging NuGet 包(仅限 Android 的条件)
  • 在 API 33+ 上请求 POST_NOTIFICATIONS 权限
  • 在发送首条通知前创建通知渠道(API 26+)
  • OnNewToken 始终调用 RegisterAsync
  • 在清单中注册 FirebaseMessagingService,并配置 MESSAGING_EVENT intent 过滤器
iOS
  • 在 Apple Developer 门户中启用 Push Notifications 功能
  • 将 APNs 密钥(.p8)上传到 Azure Notification Hub
  • 配置 Entitlements.plist,将 aps-environment 设为 development 或 production
  • 在 .csproj 中设置 CodesignEntitlements
  • 获得授权后,在主线程上调用 RegisterForRemoteNotifications
  • 将设备令牌转换为小写十六进制字符串(不含连字符)
后端
  • 使用 FCM V1 JSON 和 APNS 密钥配置 Azure Notification Hub
  • BaseAddress 以 / 结尾
  • 将标签表达式分成每组 ≤20 个进行批处理
  • 平台字符串:"fcmv1" 和 "apns"(不是旧版值)

架构概览

MAUI app → ASP.NET Core backend → Azure Notification Hub → FCM / APNS → device

完整实现模板请参阅 references/push-notifications-api.md。

评论

支持 Markdown