push-notification-best-practices
Comprehensive mobile push notification guide for iOS (APNS) and Android (FCM). Use when setting up push notifications, debugging delivery issues, implementing background/foreground handlers, managing push tokens, integrating deep linking, or troubleshooting platform-specific issues.
What this skill does
# 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:**
```javascript
// 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: BackgrounRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.