push-notification-best-practices

📁 clix-so/skills 📅 Jan 26, 2026
25
总安装量
25
周安装量
#7788
全站排名
安装命令
npx skills add https://github.com/clix-so/skills --skill push-notification-best-practices

Agent 安装分布

claude-code 21
opencode 20
gemini-cli 19
codex 18
cursor 15
antigravity 14

Skill 文档

Push Notification Best Practices

Overview

Comprehensive guide for implementing and troubleshooting push notifications in mobile applications. Covers iOS (APNS), Android (FCM), React Native, Expo, and Flutter platforms with platform-specific configurations, token management, message handling, and deep linking patterns.

Platform Support Matrix

Platform Offline Push Notification Bar Click Navigation In-App Toast Background Handler
iOS APNS System Deep Link Custom data-only payload
Android FCM System Intent Custom data-only payload
React Native APNS/FCM System React Navigation Custom setBackgroundMessageHandler
Expo Expo Push System Linking Custom TaskManager
Flutter APNS/FCM System Navigator Custom onBackgroundMessage

Decision Trees

Permission Request Timing

When to request notification permission?

User installing app
        |
        v
  [First launch?] ──Yes──> [Show value proposition first]
        |                          |
        No                         v
        |                  [User action triggers need?]
        v                          |
  [Already granted?]              Yes
        |                          |
       Yes                         v
        |                  [Request permission] ──> 70-80% acceptance rate
        v
  [Notifications ready]
Timing Acceptance Rate Use Case
Immediate (app launch) 15-20% Low engagement apps
After onboarding 40-50% Standard apps
User-initiated action 70-80% High engagement apps

Recommendation: Request after explaining value or when user enables a related feature.

Silent vs Visible Notification

Which payload type should I use?

[What's the purpose?]
        |
        +──> Time-sensitive user alert ──> Visible (notification payload)
        |
        +──> Background data sync ──> Silent (data-only payload)
        |
        +──> Custom UI required ──> Silent (data-only payload)
        |
        +──> Need background processing ──> Silent (data-only payload)
Scenario Payload Type Reason
New message alert Visible User needs immediate attention
Order status update Visible Time-sensitive information
Background sync Silent No user interruption needed
Custom notification UI Silent Full control over display
Update badge count Silent Background processing needed

Extension Strategy (iOS)

When to use Notification Service Extension?

  • Need to modify notification content before display
  • Need to download and attach media (images, videos)
  • Need to decrypt end-to-end encrypted payloads
  • Need to add action buttons dynamically

When to use Notification Content Extension?

  • Need custom notification UI beyond system template
  • Need interactive elements in expanded view

Anti-patterns (NEVER Do)

Permission Handling

NEVER Why Instead
Request permission on first launch without context 15-20% acceptance rate Explain value first, then request
Re-ask after user denies System ignores repeated requests Show settings redirect
Ignore provisional authorization Misses iOS 12+ quiet delivery Use .provisional option

Token Management

NEVER Why Instead
Cache tokens long-term Tokens can change on reinstall/restore Always use fresh token from callback
Assume token format Format varies by platform/SDK Treat as opaque string
Send token without user association Can’t target notifications Associate with userId on backend
Store tokens without device ID Duplicate tokens per user Use deviceId as unique key

Message Handling

NEVER Why Instead
Use notification payload for background processing onMessageReceived not called in background Use data-only payload
Rely on silent notifications for time-critical delivery Delivery not guaranteed Use visible notifications
Execute heavy operations in background handler System kills app after ~30 seconds Queue work, process quickly
Forget to handle both payload types Missing notifications Handle notification + data payloads

iOS Specific

NEVER Why Instead
Register for notifications before delegate setup Delegate methods not called Set delegate before registerForRemoteNotifications()
Skip serviceExtensionTimeWillExpire() implementation Content modification fails Always implement fallback
Use .p12 certificates Expires yearly, deprecated Use .p8 authentication key

Android Specific

NEVER Why Instead
Skip NotificationChannel creation Notifications don’t appear on Android 8.0+ Create channel at app start
Use priority normal for background handlers Doze mode blocks delivery Use priority high
Use colored notification icons Android ignores colors, shows white square Use white-on-transparent icons

Skill Format

Each rule file follows a hybrid format for fast lookup and deep understanding:

  • Quick Pattern: Incorrect/Correct code snippets for immediate pattern matching
  • When to Apply: Situations where this rule is relevant
  • Deep Dive: Full context with step-by-step guides and platform-specific details
  • Common Pitfalls: Common mistakes and how to avoid them
  • Related Rules: Cross-references to related patterns

Impact ratings: CRITICAL (fix immediately), HIGH (significant improvement), MEDIUM (worthwhile optimization)

When to Apply

Reference these guidelines when:

  • Setting up push notifications in a mobile app
  • Debugging push notification delivery issues
  • Implementing background notification handlers
  • Integrating deep linking with push notifications
  • Managing push tokens and device registration
  • Troubleshooting platform-specific push issues
  • Reviewing push notification code for reliability

Priority-Ordered Guidelines

Priority Category Impact Prefix
1 iOS Setup CRITICAL ios-
2 Android Setup CRITICAL android-
3 Token Management HIGH token-
4 Message Handling HIGH message-
5 Deep Linking MEDIUM deeplink-
6 Infrastructure MEDIUM infra-

Quick Reference

Critical: iOS Setup

Setup checklist:

  • Generate APNs authentication key (.p8) from Apple Developer
  • Upload to Firebase Console with Key ID and Team ID
  • Enable Push Notifications capability in Xcode
  • Set UNUserNotificationCenter delegate in didFinishLaunchingWithOptions
  • Request notification authorization before registering
  • Implement foreground presentation options

Critical: Android Setup

Setup checklist:

  • Add google-services.json to app/ directory
  • Apply google-services Gradle plugin
  • Create NotificationChannel (Android 8.0+)
  • Request POST_NOTIFICATIONS permission (Android 13+)
  • Implement FirebaseMessagingService
  • Set notification icon (transparent background + white)
  • Use priority ‘high’ for Doze mode compatibility

High: Token Management

Token lifecycle:

// 1. Register token with server
const token = await getToken();
await registerToken(token, userId);

// 2. Handle token refresh
onTokenRefresh((newToken) => {
  updateTokenOnServer(newToken, userId);
});

// 3. Handle invalidation
if (error.code === 'DeviceNotRegistered') {
  deleteTokenFromDatabase(token);
}

High: Message Handling

Payload types:

  • data-only: Background handler runs on both platforms
  • notification + data: iOS/Android behavior differs
    • iOS: Always shows notification
    • Android: Background = system tray, Foreground = onMessageReceived

Priority settings:

  • Use priority: 'high' for time-sensitive notifications
  • Required for Android Doze mode background handlers

Rules

Full documentation with code examples in rules/:

iOS Setup (ios-*)

File Impact Description
ios-apns-auth-key.md CRITICAL APNs authentication key setup
ios-delegate-setup.md CRITICAL UNUserNotificationCenter delegate configuration
ios-permission-request.md CRITICAL Notification permission request flow
ios-token-registration.md HIGH APNS token registration and handling
ios-foreground-display.md HIGH Display notifications in foreground
ios-method-swizzling.md MEDIUM Method Swizzling management
ios-extension-build.md MEDIUM Notification Service Extension setup

Android Setup (android-*)

File Impact Description
android-notification-channel.md CRITICAL Notification channel creation (Android 8.0+)
android-permission.md CRITICAL POST_NOTIFICATIONS runtime permission (Android 13+)
android-google-services.md CRITICAL Firebase project configuration
android-messaging-service.md HIGH FirebaseMessagingService implementation
android-notification-icon.md MEDIUM Notification icon asset requirements
android-priority-high.md HIGH Priority ‘high’ for Doze mode

Token Management (token-*)

File Impact Description
token-registration.md HIGH Token registration with backend
token-refresh.md HIGH Token refresh handling
token-invalidation.md MEDIUM DeviceNotRegistered error handling

Message Handling (message-*)

File Impact Description
message-data-vs-notification.md CRITICAL data vs notification payload differences
message-background-handler.md HIGH Background message processing
message-foreground-handler.md HIGH Foreground notification display

Deep Linking (deeplink-*)

File Impact Description
deeplink-navigation-conflict.md MEDIUM React Navigation conflict resolution
deeplink-terminated-state.md MEDIUM Deep link handling when app is terminated

Infrastructure (infra-*)

File Impact Description
infra-firewall-ports.md MEDIUM Network firewall configuration
infra-backup-fid.md MEDIUM Firebase Installation ID backup exclusion
infra-rate-limiting.md MEDIUM Push notification rate limiting

Best Practices

File Impact Description
permission-timing.md HIGH Permission request timing optimization (70-80% acceptance)
testing-debugging.md HIGH Testing tools, debugging techniques, payload validation

Searching Rules

# Find rules by keyword
grep -l "apns" rules/
grep -l "fcm" rules/
grep -l "token" rules/
grep -l "background" rules/
grep -l "permission" rules/
grep -l "deeplink" rules/

Problem → Rule Mapping

Problem Start With
iOS not receiving push ios-apns-auth-key → ios-delegate-setup
Android not receiving push android-google-services → android-notification-channel
Push not working in background android-priority-high → message-background-handler
Push not visible in foreground ios-foreground-display or message-foreground-handler
Token missing/expired token-registration → token-refresh
Deep link conflict error deeplink-navigation-conflict
Notification icon broken (Android) android-notification-icon
Failed on corporate network infra-firewall-ports
Background handler not called (Android) android-priority-high → message-data-vs-notification
userNotificationCenter not called (iOS) ios-delegate-setup
404 error after backup restore infra-backup-fid
Send failed (429 error) infra-rate-limiting
Low permission acceptance rate permission-timing → ios-permission-request
How to debug/test push testing-debugging
Cannot test locally testing-debugging → ios-apns-auth-key

Platform-Specific Notes

iOS (APNS)

  • Requires Apple Developer account and APNs authentication key (.p8)
  • Different behavior for Development vs Production builds
  • Delegate must be set before other SDK initialization
  • Method Swizzling can interfere with delegate calls

Android (FCM)

  • Requires google-services.json from Firebase Console
  • NotificationChannel required for Android 8.0+
  • Runtime permission required for Android 13+
  • Doze mode requires priority: 'high' for background handlers
  • Notification icons must be monochrome (white on transparent)

React Native

  • Common issue: gcm.message_id required for foreground notifications
  • Deep linking conflicts with React Navigation
  • Terminated state requires native → JS bridge pattern

Expo

  • ExpoPushToken format: ExponentPushToken[...]
  • Rate limit: 600 push notifications per second per project
  • Development builds required for SDK 53+
  • Use eas credentials for APNs key management

Full Compiled Document

For the complete guide with all rules expanded: AGENTS.md

Attribution

Based on push notification troubleshooting guides and Firebase Cloud Messaging official documentation.