maui-push-notifications について
.NET MAUI の Android・iOS 向けプッシュ通知の実装とトラブルシューティングを扱うスキルです。プラットフォーム別チェックリストに加え、トークン登録、権限、通知チャンネル、Azure Notification Hub の制約を説明します。
主な機能
- 01トークン更新と再登録の解説
- 02Android の通知権限とチャンネルの確認
- 03iOS APNs の設定要件
- 04プラットフォーム登録値の説明
- 05Azure Notification Hub のタグ上限への対応
- 06Android、iOS、バックエンドのチェックリスト
活用シーン
- 01Android 通知が届かない問題の調査
- 02トークン登録と更新の問題のデバッグ
- 03実機向け iOS プッシュ設定の準備
- 04Azure 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 ではチャンネルを明示的に作成する必要があります | 送信前にチャンネルを作成してください |
20 個を超えるタグで SendNotificationAsync が例外をスローする | Azure NH のタグ式の上限です | タグを 20 個ずつのグループに分けてください |
デバイス登録時に 422 が発生する | プラットフォーム文字列が一致していません | "gcm" ではなく "fcmv1" と "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);
}
⚠️ "gcm" ではなく "fcmv1" を使用する
従来の "gcm" プラットフォーム文字列を使用すると、デバイス登録時に 422 エラーが発生します。Android では必ず "fcmv1" を、iOS では "apns" を使用してください。
⚠️ iOS シミュレーターではプッシュ通知を受信できない
APNS は実機の iOS デバイスでのみ動作します。シミュレーターではプッシュ通知の登録が気づかないうちに無視されます。
プラットフォーム別チェックリスト
Android
-
<GoogleServicesJson>を.csprojに設定し、Platforms/Android/にgoogle-services.jsonを配置する - NuGet パッケージ
Xamarin.Firebase.Messagingを追加する(Android のみを対象とする条件付き設定) - API 33 以降で
POST_NOTIFICATIONS権限をリクエストする - 最初の通知を送信する前に通知チャンネルを作成する(API 26 以降)
-
OnNewTokenから必ずRegisterAsyncを呼び出す -
FirebaseMessagingServiceをMESSAGING_EVENTインテントフィルターとともにマニフェストに登録する
iOS
- Apple Developer ポータルでプッシュ通知機能を有効にする
- APNs キー(
.p8)を Azure Notification Hub にアップロードする -
aps-environmentをdevelopmentまたはproductionに設定したEntitlements.plistを用意する -
.csprojでCodesignEntitlementsを設定する - 認証許可後、メインスレッドで
RegisterForRemoteNotificationsを呼び出す - デバイストークンを小文字の 16 進文字列に変換する(ハイフンなし)
バックエンド
- Azure Notification Hub に FCM V1 JSON と APNS キーを設定する
-
BaseAddressの末尾に/を付ける - タグ式を 20 個以下のグループに分ける
- プラットフォーム文字列には従来の値ではなく
"fcmv1"と"apns"を使用する
アーキテクチャの概要
MAUI app → ASP.NET Core backend → Azure Notification Hub → FCM / APNS → device
実装テンプレートの全容については、references/push-notifications-api.md を参照してください。