
Push Notification Setup
- 529 installs
- 305 repo stars
- Updated March 4, 2026
- aj-geddes/useful-ai-prompts
push-notification-setup is a Claude Code skill that scaffolds complete iOS and Android push notification flows with Firebase Cloud Messaging and APNs for developers building React Native engagement features.
About
push-notification-setup is a React Native mobile skill from aj-geddes/useful-ai-prompts that implements end-to-end push notifications for iOS and Android. It covers Firebase Cloud Messaging setup, Apple Push Notification service configuration, in-app notification handling, deep-link payloads, and backend integration patterns. Developers reach for push-notification-setup when adding real-time alerts, re-engagement nudges, or deep-link opens from notification taps rather than wiring FCM and APNs piecemeal from scattered docs. The skill includes quick-start steps, reference guides, and best-practice checklists for permissions, token registration, and foreground versus background delivery behavior on both platforms.
- Covers Firebase Cloud Messaging and Apple Push Notification service setup
- Handles permission requests, token management, and refresh listeners
- Includes deep linking, silent/background notifications, and analytics tracking
- Provides backend integration patterns for token storage
- Platform-specific code paths for iOS and Android
Push Notification Setup by the numbers
- 529 all-time installs (skills.sh)
- Ranked #299 of 1,039 Mobile Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/aj-geddes/useful-ai-prompts --skill push-notification-setupAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 529 |
|---|---|
| repo stars | ★ 305 |
| Last updated | March 4, 2026 |
| Repository | aj-geddes/useful-ai-prompts ↗ |
How do you set up React Native push notifications?
Quickly scaffold complete push notification flows for React Native apps targeting both iOS and Android.
Who is it for?
React Native developers adding cross-platform push alerts with Firebase and native iOS/Android services.
Skip if: Web-only PWA projects or native Swift/Kotlin apps that do not use React Native.
When should I use this skill?
A developer asks to implement push notifications, FCM, APNs, or notification deep links in a React Native app.
What you get
FCM and APNs configuration, client notification handlers, token registration flow, and backend integration scaffolding.
- FCM/APNs config steps
- Client handler scaffolding
Files
Push Notification Setup
Table of Contents
Overview
Implement comprehensive push notification systems for iOS and Android applications using Firebase Cloud Messaging and native platform services.
When to Use
- Sending real-time notifications to users
- Implementing user engagement features
- Deep linking from notifications to specific screens
- Handling silent/background notifications
- Tracking notification analytics
Quick Start
Minimal working example:
import messaging from "@react-native-firebase/messaging";
import { Platform } from "react-native";
export async function initializeFirebase() {
try {
if (Platform.OS === "ios") {
const permission = await messaging().requestPermission();
if (permission === messaging.AuthorizationStatus.AUTHORIZED) {
console.log("iOS notification permission granted");
}
}
const token = await messaging().getToken();
console.log("FCM Token:", token);
await saveTokenToBackend(token);
messaging().onTokenRefresh(async (newToken) => {
await saveTokenToBackend(newToken);
});
messaging().onMessage(async (remoteMessage) => {
console.log("Notification received:", remoteMessage);
showLocalNotification(remoteMessage);
});
// ... (see reference guides for full implementation)Reference Guides
Detailed implementations in the references/ directory:
| Guide | Contents |
|---|---|
| Firebase Cloud Messaging Setup | Firebase Cloud Messaging Setup |
| iOS Native Setup with Swift | iOS Native Setup with Swift |
| Android Setup with Kotlin | Android Setup with Kotlin |
| Flutter Implementation | Flutter Implementation |
Best Practices
✅ DO
- Request permission before sending notifications
- Implement token refresh handling
- Use different notification channels by priority
- Validate tokens regularly
- Track notification delivery
- Implement deep linking
- Handle notifications in all app states
- Use silent notifications for data sync
- Store tokens securely on backend
- Provide user notification preferences
- Test on real devices
❌ DON'T
- Send excessive notifications
- Send without permission
- Store tokens insecurely
- Ignore notification failures
- Send sensitive data in payload
- Use notifications for spam
- Forget to handle background notifications
- Make blocking calls in handlers
- Send duplicate notifications
- Ignore user preferences
Android Setup with Kotlin
Android Setup with Kotlin
// AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application>
<service
android:name=".services.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
</manifest>
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
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)
println("FCM Token: $token")
saveTokenToBackend(token)
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
val title = remoteMessage.notification?.title ?: "Notification"
val body = remoteMessage.notification?.body ?: ""
val deepLink = remoteMessage.data["deepLink"] ?: ""
if (remoteMessage.notification != null) {
showNotification(title, body, deepLink)
}
}
private fun showNotification(title: String, message: String, deepLink: String = "") {
val channelId = "default_channel"
createNotificationChannel(channelId)
val intent = Intent(this, MainActivity::class.java).apply {
if (deepLink.isNotEmpty()) {
data = android.net.Uri.parse(deepLink)
}
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
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(message)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.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 Channel",
NotificationManager.IMPORTANCE_DEFAULT
)
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
private fun saveTokenToBackend(token: String) {
println("Saving token to backend: $token")
}
}Firebase Cloud Messaging Setup
Firebase Cloud Messaging Setup
import messaging from "@react-native-firebase/messaging";
import { Platform } from "react-native";
export async function initializeFirebase() {
try {
if (Platform.OS === "ios") {
const permission = await messaging().requestPermission();
if (permission === messaging.AuthorizationStatus.AUTHORIZED) {
console.log("iOS notification permission granted");
}
}
const token = await messaging().getToken();
console.log("FCM Token:", token);
await saveTokenToBackend(token);
messaging().onTokenRefresh(async (newToken) => {
await saveTokenToBackend(newToken);
});
messaging().onMessage(async (remoteMessage) => {
console.log("Notification received:", remoteMessage);
showLocalNotification(remoteMessage);
});
messaging().setBackgroundMessageHandler(async (remoteMessage) => {
if (remoteMessage.data?.type === "sync") {
syncData();
}
});
messaging()
.getInitialNotification()
.then((remoteMessage) => {
if (remoteMessage) {
handleNotificationOpen(remoteMessage);
}
});
messaging().onNotificationOpenedApp((remoteMessage) => {
handleNotificationOpen(remoteMessage);
});
} catch (error) {
console.error("Firebase initialization failed:", error);
}
}
export async function saveTokenToBackend(token) {
try {
const response = await fetch("https://api.example.com/device-tokens", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
token,
platform: Platform.OS,
timestamp: new Date().toISOString(),
}),
});
if (!response.ok) {
console.error("Failed to save token");
}
} catch (error) {
console.error("Error saving token:", error);
}
}
function handleNotificationOpen(remoteMessage) {
const { data } = remoteMessage;
if (data?.deepLink) {
navigationRef.navigate(data.deepLink, JSON.parse(data.params || "{}"));
}
}Flutter Implementation
Flutter Implementation
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
class NotificationHandler {
static Future<void> initialize(NavigatorState navigator) async {
final settings = await FirebaseMessaging.instance.requestPermission(
alert: true,
sound: true,
badge: true,
);
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
print('Notification permission granted');
}
final token = await FirebaseMessaging.instance.getToken();
print('FCM Token: $token');
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Received: ${message.notification?.title}');
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
_handleDeepLink(navigator, message.data);
});
final initialMessage = await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) {
_handleDeepLink(navigator, initialMessage.data);
}
}
static void _handleDeepLink(NavigatorState navigator, Map<String, dynamic> data) {
final deepLink = data['deepLink'] as String?;
if (deepLink != null) {
navigator.pushNamed(deepLink);
}
}
}iOS Native Setup with Swift
iOS Native Setup with Swift
import UIKit
import UserNotifications
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
requestNotificationPermission()
if let remoteNotification = launchOptions?[.remoteNotification] as? [AnyHashable: Any] {
handlePushNotification(remoteNotification)
}
return true
}
func requestNotificationPermission() {
UNUserNotificationCenter.current().requestAuthorization(
options: [.alert, .sound, .badge]
) { granted, error in
if granted {
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
}
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
print("Device Token: \(token)")
saveTokenToBackend(token: token)
}
func application(
_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error
) {
print("Failed to register: \(error)")
}
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler:
@escaping (UNNotificationPresentationOptions) -> Void
) {
let userInfo = notification.request.content.userInfo
if #available(iOS 14.0, *) {
completionHandler([.banner, .sound, .badge])
} else {
completionHandler([.sound, .badge])
}
handlePushNotification(userInfo)
}
func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let userInfo = response.notification.request.content.userInfo
handlePushNotification(userInfo)
completionHandler()
}
private func handlePushNotification(_ userInfo: [AnyHashable: Any]) {
if let deepLink = userInfo["deepLink"] as? String {
NotificationCenter.default.post(
name: NSNotification.Name("openDeepLink"),
object: deepLink
)
}
}
private func saveTokenToBackend(token: String) {
let urlString = "https://api.example.com/device-tokens"
guard let url = URL(string: urlString) else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body: [String: Any] = ["token": token, "platform": "ios"]
request.httpBody = try? JSONSerialization.data(withJSONObject: body)
URLSession.shared.dataTask(with: request).resume()
}
}#!/bin/bash
# validate-api.sh - Validate API specification
# Usage: ./validate-api.sh <openapi_spec>
set -euo pipefail
SPEC_FILE="${{1:?Usage: $0 <openapi_spec>}}"
echo "Validating API spec: $SPEC_FILE"
# TODO: Add API validation
# - Validate OpenAPI/Swagger syntax
# - Check endpoint naming conventions
# - Verify response schemas
# - Check for required headers
# - Validate authentication definitions
echo "API validation complete."
# API Endpoint Scaffold
# TODO: Customize for your API framework
openapi: "3.0.3"
info:
title: "API Service"
version: "1.0.0"
paths:
/api/v1/resource:
get:
summary: "List resources"
# TODO: Define parameters and responses
responses:
"200":
description: "Success"
post:
summary: "Create resource"
# TODO: Define request body and responses
responses:
"201":
description: "Created"
Related skills
FAQ
Which platforms does push-notification-setup cover?
push-notification-setup covers iOS and Android React Native apps using Firebase Cloud Messaging and Apple Push Notification service, including handlers, permissions, and backend integration.
What notification features does push-notification-setup include?
push-notification-setup includes real-time alerts, user engagement flows, deep-link handling from notification taps, token registration, and foreground versus background delivery patterns.