# Framework Recipes

Ready-made push setups for Swift (native iOS), Kotlin and Jetpack Compose (native Android), bare React Native, Expo and Flutter — the packages to install, getting the token, registering it, and showing Android pushes.

Every language and framework follows the same four steps — only "get the token" changes:

1. **Get the platform token**

   - **iOS:** the APNs device token (hex string) from your app delegate.
   - **Android:** the FCM registration token.
   - **Web:** the browser's `PushSubscription` — see [Web Push](/docs/push/web-push).

   Whichever library hands you the token is fine — APNs directly on iOS, FCM's SDK on Android, `firebase_messaging` on Flutter, `expo-notifications`' `getDevicePushTokenAsync()` in an Expo development build.

2. **Register it with a stable deviceId**

   ```text
   POST https://app.nativenotify.com/api/universal/device/register
   ```

   Send the token in `tokens.apnsToken` (iOS) or `tokens.fcmToken` (Android) with `platform` (`"ios"` / `"android"`) and a `deviceId` you persist across launches — the [Quickstart](/docs/push/quickstart) has a minimal example per platform, and [Device Registration](/docs/push/registration) is the full contract.

3. **Save the app's push credentials**

   The FCM service account (Android) and Apple `.p8` key (iOS) your sends go out with — [Push Credentials](/docs/push/credentials).

4. **Verify, then send**

   Prove one device with a [test send](/docs/push/verification), then send to an audience — every registered device (`all`), a device list, a subscriber list or a [group](/docs/push/groups). See [Send Notifications](/docs/push/sending).

> **Android shows nothing on its own:**
>
> Native Notify's Android pushes are FCM **data** messages (`title`, `message`, and `body` = your `pushData` as JSON). A native Kotlin, bare React Native or Flutter app must post the notification itself from its message handler — each recipe shows how. A test send reports `accepted` either way, because FCM accepted the message.

## Recipes

| Framework                 | Token source                                              | Recipe                                                       |
| ------------------------- | --------------------------------------------------------- | ------------------------------------------------------------ |
| Swift (native iOS)        | `UIApplicationDelegate` + APNs                            | [Swift recipe](/docs/push/recipes/swift)                     |
| Kotlin (native Android)   | `FirebaseMessaging`                                       | [Kotlin recipe](/docs/push/recipes/kotlin)                   |
| Jetpack Compose (Android) | `FirebaseMessaging` + `rememberLauncherForActivityResult` | [Jetpack Compose recipe](/docs/push/recipes/jetpack-compose) |
| Bare React Native         | `@react-native-firebase/messaging` / APNs delegate        | [Bare React Native recipe](/docs/push/recipes/react-native)  |
| Expo (React Native)       | `expo-notifications` (a development build)                | [Expo recipe](/docs/push/recipes/expo)                       |
| Flutter                   | `firebase_messaging`                                      | [Flutter recipe](/docs/push/recipes/flutter)                 |
| Web (browsers)            | `PushManager.subscribe()`                                 | [Web Push recipe](/docs/push/web-push)                       |

Anything not listed — .NET, Unity, a KMP app, a backend that holds device tokens — registers with the same JSON contract. Start from the [Quickstart](/docs/push/quickstart) or [Device Registration](/docs/push/registration).
