# Framework Recipes

The common pattern for any framework — get the native APNs/FCM token, register it with a stable deviceId, verify with a test send — with per-framework recipes for Expo, bare React Native, Flutter, Swift and Kotlin.

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

1. **Get the platform token**

   - **iOS:** the APNs device token (hex string) — delivered to your app delegate / messaging library.
   - **Android:** the FCM registration token.

   Whichever library hands you the token is fine — FCM's SDK on Android, APNs directly on iOS, `firebase_messaging` on Flutter, `expo-notifications`' `getDevicePushTokenAsync()` in a 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), plus a `deviceId` you persist across launches, and `subscriberId` when the user is logged in. Full contract: [Device Registration](/docs/universal-push/registration).

3. **Verify with a test send**

   Send to that exact `deviceId` and read the honest result — [Verify Delivery](/docs/universal-push/verification).

4. **Send to an audience**

   All devices, a device list, or a subscriber list — [Send Notifications](/docs/universal-push/sending). And remember the app needs its [push credentials](/docs/universal-push/credentials) saved before anything is actually delivered.

## Recipes

| Framework               | Token source                                         | Recipe                                                                |
| ----------------------- | ---------------------------------------------------- | --------------------------------------------------------------------- |
| Expo (React Native)     | SDK (Expo path) or `expo-notifications` native token | [Expo recipe](/docs/universal-push/recipes/expo)                      |
| Bare React Native       | `@react-native-firebase/messaging` / APNs delegate   | [Bare React Native recipe](/docs/universal-push/recipes/react-native) |
| Flutter                 | `firebase_messaging`                                 | [Flutter recipe](/docs/universal-push/recipes/flutter)                |
| Swift (native iOS)      | `UIApplicationDelegate` + APNs                       | [Swift recipe](/docs/universal-push/recipes/swift)                    |
| Kotlin (native Android) | `FirebaseMessaging`                                  | [Kotlin recipe](/docs/universal-push/recipes/kotlin)                  |

> **Not listed?:**
>
> The recipes only differ in how you obtain a token. .NET, Unity, a KMP app, a backend that holds device tokens — anything that can produce an APNs `.p8`-signed token or an FCM token through its SDK can register with the same JSON contract. Start from [Device Registration](/docs/universal-push/registration).
