capacitor-push-notifications について
capacitor-push-notificationsは、Capacitorアプリのプッシュ通知導入と問題調査を支援するスキルで、主に公式の@capacitor/push-notificationsプラグインを扱います。iOSとAndroidの設定、トークン登録、フォアグラウンド表示、実機検証を案内します。
主な機能
- 01プッシュ通知プラグインの選定と導入
- 02iOSのAPNsとAndroidのFirebase設定
- 03リスナー、権限、トークンの順次登録
- 04フォアグラウンド通知の表示設定
- 05配信確認と一般的なエラーの調査
活用シーン
- 01Capacitorアプリへのリモートプッシュ追加
- 02登録トークンが発火しない問題やOS間の差異の調査
- 03フォアグラウンドとバックグラウンドの表示差への対処
- 04Android 13以降の権限と通知配信の確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ cap-go/ capgo-skills --skill capacitor-push-notificationsインストール後、Claude Code で/capacitor-push-notificationsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
metadata.jsonreferences/android-setup.mdios-setup.mdsending.md詳細
Capacitor のプッシュ通知
使用するタイミング
以下の場合に使用します:
- Capacitor アプリにリモートプッシュ通知(FCM/APNs)を追加する場合
registration/registrationErrorが一度も発火しない場合、またはトークンが一方のプラットフォームでしか機能しない場合- iOS のトークンが 64 桁の 16 進数の APNs トークンで、バックエンドが FCM トークンを想定している場合
- 通知がバックグラウンドでは届くのにフォアグラウンドでは届かない場合(またはその逆)
- Android 13 以降でプロンプトが表示されず、通知も届かない場合
- Capacitor 8.5(UIScene)または 9(
alertプレゼンテーションオプションが削除)にアップグレードする場合
以下には使用しないでください:
https:///myapp://リンクからアプリを開く場合:capacitor-deep-linking- AppDelegate のコードを SceneDelegate に移す場合:
capacitor-uiscene-migration - デバイスログの取得:
ios-android-logs - ほかのネイティブプラグインの選定:
capacitor-plugins
まずプラグインを選択する(不明な場合はユーザーに確認してください)
| 必要な機能 | プラグイン |
|---|---|
| 公式プラグイン。iOS では APNs トークン、Android では FCM トークン | @capacitor/push-notifications |
| 両プラットフォームで FCM トークン、トピック、Firebase を優先するバックエンド | @capgo/capacitor-firebase-messaging |
| Capgo が管理する配信(ダッシュボードキャンペーン、バッジ、サイレントなライブアップデートの確認、自前のプッシュサーバー不要) | @capgo/capacitor-notifications |
| ローカル通知のみ、リッチレイアウト | @capgo/capacitor-rich-notifications または @capacitor/local-notifications |
このファイルの残りの部分では @capacitor/push-notifications を扱います。Capgo のプラグインについては https://capgo.app/docs/plugins/firebase-messaging/ または https://capgo.app/docs/plugins/notifications/getting-started/ を参照してください。
ワークフロー
- 確認:
package.jsonのバージョン(@capacitor/core、@capacitor/push-notifications)、capacitor.config.*のplugins.PushNotifications、ios/App/App/AppDelegate.swift、ios/App/App/*.entitlements、android/app/google-services.json、android/variables.gradle、AndroidManifest.xmlを確認します。 - インストール:
npm install @capacitor/push-notifications && npx cap sync。 - iOS:機能、APNs キー、AppDelegate での転送。詳細:references/ios-setup.md。
- Android:
google-services.json、チャンネル、アイコン、権限。詳細:references/android-setup.md。 - JS:まずリスナーを登録し、次に権限を要求してから
register()を呼び出します(以下を参照)。 - バックエンド:テストメッセージを送信します。ペイロードの形式:references/sending.md。
- 物理デバイスで以下のチェックリストを使って検証します。
トピックを扱う場合に限り、該当するリファレンスを読み込んでください。
JS の登録(順序が重要)
import { PushNotifications } from '@capacitor/push-notifications';
export async function initPush() {
// 1. Listeners before register(), or the first token is missed
await PushNotifications.addListener('registration', ({ value }) => sendTokenToServer(value));
await PushNotifications.addListener('registrationError', (err) => console.error('push reg', err.error));
await PushNotifications.addListener('pushNotificationReceived', (n) => {
// foreground only (and Android data-only while app is alive)
});
await PushNotifications.addListener('pushNotificationActionPerformed', ({ notification, actionId }) => {
routeFromNotification(notification.data); // tap handling
});
// 2. Permission (required on iOS and Android 13+ / targetSdk 33+)
let perm = await PushNotifications.checkPermissions();
if (perm.receive === 'prompt' || perm.receive === 'prompt-with-rationale') {
perm = await PushNotifications.requestPermissions();
}
if (perm.receive !== 'granted') return; // explain + link to settings, do not loop prompts
// 3. Register
await PushNotifications.register();
}
注意点:
- コールドスタート時のタップによる
pushNotificationActionPerformedを捕捉できるよう、起動時にinitPush()を呼び出してください。 - トークンはローテーションします。
registrationの値を毎回サーバーに送信し、ユーザーとデバイスの組み合わせで upsert してください。 - iOS では、AppDelegate が FCM トークンに差し替えない限り、プラグインは生の APNs トークンを通知します(ios-setup を参照)。APNs トークンを FCM に送信すると
messaging/invalid-registration-tokenエラーになります。 - その価値を説明できるユーザー操作の後に権限を要求してください。iOS でシステムプロンプトが表示されるのは一度だけです。
フォアグラウンドでの表示
// capacitor.config.ts
plugins: {
PushNotifications: {
presentationOptions: ['badge', 'sound', 'banner', 'list'],
},
},
bannerとlistは、非推奨の iOS のalertに代わるものです。Capacitor 9 では iOS のalertが削除されるため、アップグレード時に置き換えてください。badgeは iOS のみです。- 空の配列を指定すると、フォアグラウンドでは何も表示されません。
pushNotificationReceivedを使って独自に処理してください。
Capacitor のバージョンに関する注意事項
| バージョン | 変更点 |
|---|---|
| 7 | firebaseMessagingVersion のデフォルトは 24.1.0 |
| 8 | firebaseMessagingVersion のデフォルトは 25.0.1 |
| 8.5 | UIScene ライフサイクル。リモート通知のコールバック(didRegisterForRemoteNotificationsWithDeviceToken、didFailToRegister...)は引き続き AppDelegate に置き、そのまま動作します。SceneDelegate に移さないでください。AppDelegate の application(_:open:) を使っていたタップのルーティングは移す必要があります(capacitor-deep-linking を参照)。 |
| 9 | iOS の alert プレゼンテーションオプションを削除。iOS 16 が最小バージョンに。@UIApplicationMain を @main に置き換え。google-services Gradle プラグインは 4.5.0 |
検証
- iOS:
codesign -d --entitlements :- path/to/App.app | grep aps-environmentにdevelopment(デバッグ)またはproduction(TestFlight/App Store)が表示されます。 - Android:プロンプトを許可した後、
adb shell dumpsys package com.example.app | grep POST_NOTIFICATIONSにgranted=trueが表示されます。 - 実機でアプリのログに
registrationトークンが記録されます(Apple silicon 搭載の iOS シミュレーターではxcrun simctl pushでプッシュを受信できますが、APNs のテストは実機で行ってください)。 - Firebase Console(Messaging -> "Send test message")またはバックエンドから、そのトークン宛てにテストメッセージを送信します。
- 次の 3 つの状態をすべて確認します:フォアグラウンド(表示 +
pushNotificationReceived)、バックグラウンド(システムトレイ)、終了状態(タップするとpushNotificationActionPerformedが正しくルーティングされます)。 - サーバーを使わない iOS シミュレーターでのスモークテスト:
cat > /tmp/push.apns <<'EOF'
{ "Simulator Target Bundle": "com.example.app", "aps": { "alert": { "title": "Test", "body": "Hello" } }, "route": "/inbox" }
EOF
xcrun simctl push booted com.example.app /tmp/push.apns
(APNs ペイロード内の aps.alert はメッセージの内容であり、presentationOptions の変更による影響を受けません。)
エラー処理
| エラー/症状 | 原因 | 対処方法 |
|---|---|---|
no valid "aps-environment" entitlement string found for application | Push Notifications 機能が不足しているか、プロファイルが再生成されていません | Xcode で機能を追加し、再署名して、再ビルドします |
registration が iOS で一度も発生せず、エラーもない | AppDelegate が .capacitorDidRegisterForRemoteNotifications をポストしていません | AppDelegate に転送メソッドを追加します |
Default FirebaseApp is not initialized in this process(Android) | google-services.json がないか空のため、google-services プラグインが適用されていません(google-services.json not found, google-services plugin not applied. Push Notifications won't work) | ファイルを android/app/ に配置し、再ビルドします |
messaging/registration-token-not-registered | トークンが古くなっています(アプリの再インストール/データの消去) | サーバー側でトークンを削除し、次回の registration に任せます |
messaging/invalid-registration-token/BadDeviceToken | APNs トークンが FCM に送信されたか、サンドボックスのトークンが本番環境の APNs に送信されました | iOS では FCM トークンを使用する(ios-setup)か、APNs 環境を一致させます |
messaging/third-party-auth-error | APNs キーが Firebase にアップロードされていないか、Key ID/Team ID が間違っています | Firebase Project Settings -> Cloud Messaging で .p8 をアップロードします |
| Android 13 以降:何も表示されず、プロンプトも出ない | requestPermissions() が一度も呼び出されていません | 呼び出します。マニフェスト権限はプラグインによって追加されます |
| Android で通知アイコンが白い四角形になる | モノクロの通知アイコンがありません | default_notification_icon のメタデータを設定します |
| Android の通知が無音/重要度が間違っている | 重要度の低いチャンネルが作成されました(作成後に重要度を変更することはできません) | 新しいチャンネル ID を作成し、古いチャンネルを削除します |
| アプリ終了時に Android でデータのみのメッセージが無視される | プラグインはアプリのプロセスが実行中の場合にのみ配信します | ネイティブの FirebaseMessagingService(android-setup)を使用します |
| iOS でサイレントプッシュ/バックグラウンドプッシュが JS に配信されない | プラグインは iOS のサイレントプッシュに対応していません | ネイティブ処理、または @capgo/capacitor-notifications のサイレント更新チェックを使用します |
| Capacitor 9 へのアップグレード後に Firebase 関連の重複クラスエラーが発生する | 古い core-ktx/Kotlin stdlib のバージョンが固定されています | capacitor-app-upgrade-v8-to-v9 を参照してください |
リソース
- プラグイン API:https://capacitorjs.com/docs/apis/push-notifications
- Firebase ガイド:https://capacitorjs.com/docs/guides/push-notifications-firebase
- 9.0 への更新:https://capacitorjs.com/docs/updating/9-0
- Capgo Firebase Messaging:https://capgo.app/docs/plugins/firebase-messaging/
- Capgo Notifications:https://capgo.app/docs/plugins/notifications/
コメント
Markdown 対応