К основному содержанию
скилл CX Codex

capacitor-push-notifications · cap-go — скилл для Claude Code: пуш в Capacitor

Скилл для настройки и отладки удалённых пушей в Capacitor: FCM на Android, APNs на iOS. Пригодится, когда registration не срабатывает или уведомления не показываются.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add Cap-go/capgo-skills --skill capacitor-push-notifications -a claude-code
Открыть на GitHub

Что делает capacitor-push-notifications

Скилл ведёт агента по шагам: сначала смотрит package.json, capacitor.config.*, AppDelegate.swift, *.entitlements, google-services.json и AndroidManifest.xml, потом ставит @capacitor/push-notifications через npm install и npx cap sync. Дальше идёт настройка iOS (capability, ключ APNs, форвардинг токена в AppDelegate) и Android (канал, иконка, разрешение). В конце — проверка на живых устройствах.

Внутри есть готовый порядок регистрации в JS: слушатели registration, registrationError, pushNotificationReceived и pushNotificationActionPerformed вешаются до register(), иначе первый токен теряется. Разрешение запрашивается отдельно — на iOS и Android 13+ оно обязательно. Токены ротируются, поэтому каждое значение registration нужно отправлять на сервер и обновлять по паре пользователь + устройство.

Главная ловушка на iOS: плагин отдаёт сырой APNs-токен, если AppDelegate не подменит его на FCM. Отправите APNs-токен в FCM — получите messaging/invalid-registration-token. Ещё скилл разбирает presentationOptions: в Capacitor 9 опция alert на iOS удалена, вместо неё banner и list. Под Capacitor 8.5 с lifecycle UIScene колбэки remote-notification остаются в AppDelegate, переносить их в SceneDelegate не нужно. Для локальных уведомлений и обработки deep link это не тот скилл.

Какие задачи решает

  • добавить удалённые пуши в приложение на Capacitor
  • починить ситуацию, когда registration вообще не срабатывает
  • заменить APNs-токен на FCM-токен на iOS
  • выдать разрешение POST_NOTIFICATIONS на Android 13+
  • настроить показ уведомлений в foreground через presentationOptions

Примеры запросов агенту

  • Настрой удалённые пуши в Capacitor: FCM на Android, APNs на iOS
  • registration не срабатывает, помоги разобраться с токеном
  • iOS отдаёт APNs-токен вместо FCM — что поправить в AppDelegate?

Как установить capacitor-push-notifications

1Через Skills CLI (Vercel)

npx skills add Cap-go/capgo-skills --skill capacitor-push-notifications -a claude-code

2Вручную: положить файлы

~/.claude/skills/capacitor-push-notifications/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/capacitor-push-notifications/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о capacitor-push-notifications

Как установить capacitor-push-notifications в Claude?

Одной командой: npx skills add Cap-go/capgo-skills --skill capacitor-push-notifications -a claude-code. Файл скилла окажется в ~/.claude/skills/capacitor-push-notifications/SKILL.md.

Что делает capacitor-push-notifications?

Проводит агента по настройке удалённых пушей в Capacitor: установка плагина, capability и ключ APNs на iOS, google-services.json и канал на Android, порядок регистрации в JS и проверка на устройствах.

Чем этот скилл отличается от соседних?

Он про удалённые пуши. Для локальных уведомлений, обработки deep link, миграции на UIScene или сбора логов есть отдельные скиллы.

Исходный текст

SKILL.md · MIT
---
name: capacitor-push-notifications
description: Sets up and debugs remote push in Capacitor apps with @capacitor/push-notifications (FCM on Android, APNs on iOS), or Capgo alternatives @capgo/capacitor-firebase-messaging and @capgo/capacitor-notifications. Covers APNs keys, Push Notifications capability, AppDelegate `didRegisterForRemoteNotificationsWithDeviceToken` forwarding (stays in AppDelegate under the Capacitor 8.5 UIScene lifecycle), Android 13+ POST_NOTIFICATIONS permission, notification channels and icons, `firebaseMessagingVersion`, foreground `presentationOptions` (Capacitor 9 removes iOS `alert`; use `banner`/`list`), and tap routing. Use when `registration` never fires, iOS returns an APNs token instead of an FCM token, errors like "no valid aps-environment entitlement string found" appear, or notifications do not show. Do not use for local-only notifications or deep link URL handling (capacitor-deep-linking), UIScene migration (capacitor-uiscene-migration), or log capture (ios-android-logs).
---

# Push Notifications in Capacitor

## When to Use

TRIGGER when:
- Adding remote push (FCM / APNs) to a Capacitor app
- `registration` / `registrationError` never fire, or the token works on one platform only
- iOS token is a 64-hex APNs token but the backend expects an FCM token
- Notifications arrive in background but not in foreground (or vice versa)
- Android 13+ shows no prompt and nothing is delivered
- Upgrading to Capacitor 8.5 (UIScene) or 9 (`alert` presentation option removed)

Do not use:
- Opening the app from `https://` / `myapp://` links: `capacitor-deep-linking`
- Moving AppDelegate code to SceneDelegate: `capacitor-uiscene-migration`
- Device log capture: `ios-android-logs`
- Choosing other native plugins: `capacitor-plugins`

## Choose the plugin first (ask the user if unclear)

| Need | Plugin |
|------|--------|
| Official plugin; APNs token on iOS, FCM token on Android | `@capacitor/push-notifications` |
| FCM token on both platforms, topics, Firebase-first backend | `@capgo/capacitor-firebase-messaging` |
| Capgo-managed delivery (dashboard campaigns, badges, silent live-update checks, no own push server) | `@capgo/capacitor-notifications` |
| Local notifications only, rich layouts | `@capgo/capacitor-rich-notifications` or `@capacitor/local-notifications` |

The rest of this file covers `@capacitor/push-notifications`. For Capgo plugins follow https://capgo.app/docs/plugins/firebase-messaging/ or https://capgo.app/docs/plugins/notifications/getting-started/.

## Workflow

1. **Inspect**: `package.json` versions (`@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`.
2. **Install**: `npm install @capacitor/push-notifications && npx cap sync`.
3. **iOS**: capability + APNs key + AppDelegate forwarding. Details: [references/ios-setup.md](references/ios-setup.md).
4. **Android**: `google-services.json`, channel, icon, permission. Details: [references/android-setup.md](references/android-setup.md).
5. **JS**: listeners first, then permission, then `register()` (below).
6. **Backend**: send a test message. Payload shapes: [references/sending.md](references/sending.md).
7. **Verify** with the checklist below on physical devices.

Only load a reference when its topic is in play.

## JS registration (order matters)

```typescript
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();
}
```

Traps:
- Call `initPush()` at bootstrap so `pushNotificationActionPerformed` from a cold-start tap is captured.
- Tokens rotate. Send every `registration` value to the server and upsert by user + device.
- On iOS the plugin reports the raw APNs token unless AppDelegate swaps in the FCM token (see ios-setup). Sending an APNs token to FCM fails with `messaging/invalid-registration-token`.
- Ask permission after a user action that explains the value; iOS shows the system prompt only once.

## Foreground presentation

```ts
// capacitor.config.ts
plugins: {
  PushNotifications: {
    presentationOptions: ['badge', 'sound', 'banner', 'list'],
  },
},
```

- `banner` + `list` replace the deprecated iOS `alert`. **Capacitor 9 removes `alert` on iOS**; replace it when upgrading. `badge` is iOS only.
- Empty array = nothing shown in foreground; handle `pushNotificationReceived` yourself.

## Capacitor version notes

| Version | Change |
|---------|--------|
| 7 | `firebaseMessagingVersion` default 24.1.0 |
| 8 | `firebaseMessagingVersion` default 25.0.1 |
| 8.5 | UIScene lifecycle. Remote-notification callbacks (`didRegisterForRemoteNotificationsWithDeviceToken`, `didFailToRegister...`) **stay in AppDelegate** and keep working. Do not move them to SceneDelegate. Tap routing that used AppDelegate `application(_:open:)` must move (see `capacitor-deep-linking`). |
| 9 | iOS `alert` presentation option removed; iOS 16 min; `@main` replaces `@UIApplicationMain`; google-services Gradle plugin 4.5.0 |

## Verification

1. iOS: `codesign -d --entitlements :- path/to/App.app | grep aps-environment` shows `development` (debug) or `production` (TestFlight/App Store).
2. Android: `adb shell dumpsys package com.example.app | grep POST_NOTIFICATIONS` shows `granted=true` after accepting the prompt.
3. App logs a `registration` token on a real device (iOS Simulator on Apple silicon can receive pushes via `xcrun simctl push`, but test real APNs on device).
4. Send a test from Firebase Console (Messaging -> "Send test message") or your backend to that token.
5. Check all three states: foreground (presentation + `pushNotificationReceived`), background (system tray), killed (tap -> `pushNotificationActionPerformed` routes correctly).
6. iOS simulator smoke test without a server:

```bash
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
```

(`aps.alert` in the APNs payload is the message content and is unaffected by the `presentationOptions` change.)

## Error Handling

| Error / symptom | Cause | Fix |
|-----------------|-------|-----|
| `no valid "aps-environment" entitlement string found for application` | Push Notifications capability missing or profile not regenerated | Add capability in Xcode, re-sign, rebuild |
| `registration` never fires on iOS, no error | AppDelegate does not post `.capacitorDidRegisterForRemoteNotifications` | Add forwarding methods to AppDelegate |
| `Default FirebaseApp is not initialized in this process` (Android) | `google-services.json` missing/empty, so google-services plugin was not applied (`google-services.json not found, google-services plugin not applied. Push Notifications won't work`) | Put file in `android/app/`, rebuild |
| `messaging/registration-token-not-registered` | Token stale (app reinstalled / data cleared) | Delete token server-side; rely on next `registration` |
| `messaging/invalid-registration-token` / `BadDeviceToken` | APNs token sent to FCM, or sandbox token sent to production APNs | Use FCM token on iOS (ios-setup) or match APNs environment |
| `messaging/third-party-auth-error` | APNs key not uploaded to Firebase, wrong Key ID / Team ID | Upload .p8 under Firebase Project Settings -> Cloud Messaging |
| Android 13+: nothing shown, no prompt | `requestPermissions()` never called | Call it; manifest permission is added by the plugin |
| Android shows white square icon | No monochrome notification icon | Set `default_notification_icon` meta-data |
| Android notification silent / wrong importance | Channel created with low importance (importance is immutable after creation) | Create a new channel id; delete the old one |
| Data-only message ignored when app killed (Android) | Plugin only delivers while app process lives | Native `FirebaseMessagingService` (android-setup) |
| iOS silent / background push not delivered to JS | Plugin does not support iOS silent push | Native handling, or `@capgo/capacitor-notifications` silent update checks |
| Duplicate class errors with Firebase after Capacitor 9 | Old `core-ktx` / Kotlin stdlib pins | See `capacitor-app-upgrade-v8-to-v9` |

## Resources

- Plugin API: https://capacitorjs.com/docs/apis/push-notifications
- Firebase guide: https://capacitorjs.com/docs/guides/push-notifications-firebase
- Updating to 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/

© Cap-go · MIT · Cap-go/capgo-skills

Похожие скиллы

Всё по теме «Мобильная разработка» →

Сначала — capacitor-push-notifications от других авторов.

capacitor-push-notifications capawesome-team Ведёт агента по шагам: Firebase, плагин @capacitor-firebase/messaging, настройка Android, iOS и Web, APNs, токены FCM и тестовая отправка. CX Codex +1 979установок push-notifications dpearson2699 Настройка, отладка и аудит локальных и удалённых push-уведомлений в iOS и macOS на Swift. Помогает настроить APNs, категории действий и service extensions без типичных сбоев. CX Codex +1 4 200установок push-notification-setup secondsky Скилл проводит агента по настройке пуш-уведомлений через Firebase Cloud Messaging и нативные сервисы. Пригодится, когда добавляешь уведомления в приложение или разбираешься с фоновыми сообщениями. CX Codex +1 418установок capacitor-plugins capawesome-team Скилл проводит агента по установке и настройке плагинов Capacitor из шести источников, включая официальные, Capawesome и Firebase. CX Codex +1 1 800установок capacitor-expert capawesome-team Скилл-справочник по Capacitor: архитектура, CLI, плагины, интеграция с фреймворками и Capawesome Cloud. Пригодится, когда агент собирает или чинит кросс-платформенное приложение. CX Codex +1 1 100установок limrun-expo-development limrun-inc Готовит и запускает Expo и React Native приложения на Limrun: dev-client сборка, туннель Metro, правки JS и TS без повторных нативных пересборок. CX Codex +1 43 100установок argent-metro-debugger software-mansion Скилл подключает отладчик к JS-рантайму через CDP: инспектируете React-компоненты, читаете логи консоли, вычисляете код прямо в процессе. Работает с React Native (iOS, Android, Vega) и Chromium-приложениями (Electron, браузеры). CX Codex +1 26 300установок

Из того же набора29

safe-area-handling Чинит вёрстку в Capacitor-приложениях: контент под вырезом, Dynamic Island, домашним индикатором и панелью жестов Android. CX Codex +1 1 300установок capacitor-app-store Ведёт сборку Capacitor от «работает на моём устройстве» до публикации в App Store и Google Play: версии, подпись, загрузка IPA/AAB, TestFlight и треки Play. CX Codex +1 1 200установок capacitor-accessibility Скилл для ИИ-агента, который разбирает доступность Capacitor-приложений: VoiceOver, TalkBack, Dynamic Type, Switch Control и масштаб шрифта Android. CX Codex +1 1 200установок capacitor-security Проверяет приложение на Capacitor на утечки секретов, слабую защиту хранилища и транспорта, а потом помогает всё это починить. CX Codex +1 1 200установок capacitor-splash-screen Скилл разбирается, почему в приложении Capacitor мелькает белый экран или сплэш не исчезает, и правит конфиг, тему Android 12+ и iOS storyboard. CX Codex +1 1 100установок capacitor-keyboard Разбирает поведение экранной клавиатуры в приложениях на Capacitor: режимы resize на iOS, высоты событий, edge-to-edge на Android. Пригодится, когда поле ввода уезжает под клавиатуру. CX Codex +1 1 000установок tailwind-capacitor Настраивает Tailwind CSS v4 в приложениях на Capacitor и разбирает грабли мобильной вёрстки: safe-area, тёмная тема, варианты под iOS и Android. CX Codex +1 955установок framework-to-capacitor Настраивает статическую сборку Next.js, Nuxt, Angular, SvelteKit или Vite так, чтобы Capacitor упаковал её в приложение для iOS и Android. CX Codex +1 870установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой