Claude
Skills
Sign in
Back

push-notifications

Included with Lifetime
$97 forever

Multi-platform push notification skill for implementing APNs (iOS), FCM (Android), and cross-platform notification systems with rich media, deep linking, and background processing capabilities.

General

What this skill does


# Push Notifications Skill

Comprehensive push notification implementation for iOS (APNs) and Android (FCM), including rich notifications, deep linking, and background processing.

## Overview

This skill provides capabilities for implementing push notifications across iOS and Android platforms, covering certificate/key configuration, notification payload design, rich media attachments, deep linking, and background notification handling.

## Capabilities

### APNs Configuration (iOS)
- Configure APNs certificates and keys (.p8, .p12)
- Set up App ID and push entitlements
- Configure development vs production environments
- Implement UNUserNotificationCenter delegate
- Handle notification permission requests

### FCM Configuration (Android)
- Set up Firebase project and google-services.json
- Configure notification channels (Android 8.0+)
- Implement FirebaseMessagingService
- Handle FCM token registration
- Configure notification priority and visibility

### Rich Notifications
- Design notification payloads with custom data
- Implement image and media attachments
- Configure notification actions and categories
- Create interactive notification buttons
- Handle notification grouping and threading

### Deep Linking
- Implement notification-to-screen navigation
- Configure universal links from notifications
- Handle app state (foreground, background, terminated)
- Pass custom data through deep links
- Track notification tap attribution

### Background Processing
- Handle silent/background notifications
- Implement content-available processing
- Configure background fetch capabilities
- Manage notification state persistence
- Handle notification delivery reports

## Prerequisites

### iOS Development
```bash
# Ensure push notification entitlement is enabled
# In Xcode: Signing & Capabilities > + Capability > Push Notifications

# APNs Key (.p8) from Apple Developer Portal
# Or APNs Certificate (.p12) - less preferred
```

### Android Development
```groovy
// build.gradle (project)
classpath 'com.google.gms:google-services:4.4.0'

// build.gradle (app)
plugins {
    id 'com.google.gms.google-services'
}

dependencies {
    implementation platform('com.google.firebase:firebase-bom:32.7.0')
    implementation 'com.google.firebase:firebase-messaging'
}
```

### Server Requirements
```bash
# Node.js server for sending notifications
npm install firebase-admin @parse/node-apn
```

## Usage Patterns

### iOS Push Registration (SwiftUI)
```swift
import SwiftUI
import UserNotifications

@main
struct MyApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        UNUserNotificationCenter.current().delegate = self
        registerForPushNotifications()
        return true
    }

    func registerForPushNotifications() {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            guard granted else { return }
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }

    func application(_ application: UIApplication,
                     didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
        print("APNs Token: \(token)")
        // Send token to your server
    }

    func application(_ application: UIApplication,
                     didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register for notifications: \(error)")
    }

    // Handle notification when app is in foreground
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.banner, .sound, .badge])
    }

    // Handle notification tap
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        handleNotificationTap(userInfo: userInfo)
        completionHandler()
    }

    func handleNotificationTap(userInfo: [AnyHashable: Any]) {
        if let deepLink = userInfo["deep_link"] as? String {
            // Navigate to deep link destination
            NotificationCenter.default.post(name: .handleDeepLink, object: nil, userInfo: ["url": deepLink])
        }
    }
}

extension Notification.Name {
    static let handleDeepLink = Notification.Name("handleDeepLink")
}
```

### Android FCM Implementation (Kotlin)
```kotlin
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat

class MyFirebaseMessagingService : FirebaseMessagingService() {

    override fun onNewToken(token: String) {
        super.onNewToken(token)
        // Send token to your server
        sendTokenToServer(token)
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)

        // Handle data payload
        remoteMessage.data.isNotEmpty().let {
            handleDataPayload(remoteMessage.data)
        }

        // Handle notification payload (when app in foreground)
        remoteMessage.notification?.let {
            showNotification(it.title, it.body, remoteMessage.data)
        }
    }

    private fun handleDataPayload(data: Map<String, String>) {
        val deepLink = data["deep_link"]
        val customData = data["custom_data"]
        // Process data payload
    }

    private fun showNotification(title: String?, body: String?, data: Map<String, String>) {
        val channelId = "default_channel"
        createNotificationChannel(channelId)

        val intent = Intent(this, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            data.forEach { (key, value) -> putExtra(key, value) }
        }

        val pendingIntent = PendingIntent.getActivity(
            this, 0, intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        val notification = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle(title)
            .setContentText(body)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .build()

        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.notify(System.currentTimeMillis().toInt(), notification)
    }

    private fun createNotificationChannel(channelId: String) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                channelId,
                "Default Notifications",
                NotificationManager.IMPORTANCE_HIGH
            ).apply {
                description = "Default notification channel"
                enableLights(true)
                enableVibration(true)
            }

            val notificat

Related in General