# Kotlin Recipe (native Android)

Register a native Android app's FCM token with Native Notify universal push from Kotlin — FirebaseMessaging, a stable deviceId, and the registration call.

Android apps get their token from Firebase Cloud Messaging and register it with one HTTPS call.

## 1. Get the FCM token

```kotlin
import com.google.firebase.messaging.FirebaseMessaging

FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        val fcmToken = task.result
        // register it — see below
    }
}
```

Also handle rotation: `FirebaseMessagingService.onNewToken()` fires whenever FCM hands the app a fresh token.

## 2. Register with Native Notify

```kotlin
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import org.json.JSONObject

object UniversalPush {
    private val client = OkHttpClient()
    private val json = "application/json; charset=utf-8".toMediaType()

    fun register(appId: Int, appToken: String, fcmToken: String, deviceId: String, subscriberId: String? = null) {
        val body = JSONObject().apply {
            put("appId", appId)
            put("appToken", appToken)
            put("deviceId", deviceId)          // persist per install
            put("platform", "android")
            if (subscriberId != null) put("subscriberId", subscriberId)
            put("tokens", JSONObject().put("fcmToken", fcmToken))
        }

        val request = Request.Builder()
            .url("https://app.nativenotify.com/api/universal/device/register")
            .post(RequestBody.create(json, body.toString()))
            .build()

        client.newCall(request).execute().use { response ->
            // 201 {"ok":true,"device":{...},"tokens":{...}}
        }
    }
}
```

For `deviceId`, `Settings.Secure.ANDROID_ID` or a UUID you persist (e.g. `SharedPreferences` / DataStore) both work — it must be stable across launches. Call the register on every launch: it is an idempotent upsert, so repeats are cheap.

## 3. The pieces around it

- **Android 13+:** request the `POST_NOTIFICATIONS` runtime permission before expecting a token to be useful.
- **Firebase project:** the app's `google-services.json`, and the *same* project's **service-account JSON** saved as the app's credentials in Native Notify — [Push Credentials](/docs/universal-push/credentials).
- **Deregister on logout:** `POST /api/universal/device/deregister` with `{ appId, appToken, deviceId }` — a hard, idempotent delete ([Device Registration](/docs/universal-push/registration)).

## 4. Send and verify

```kotlin
// POST https://app.nativenotify.com/api/universal/notifications/send
// {"appId":123,"appToken":"yourAppToken","title":"Hello Android","message":"Delivered over FCM.","audience":{"type":"all"}}
```

Before a real blast, prove one device with [`test-send`](/docs/universal-push/verification) (`deviceId`) — FCM's answer is immediate: `accepted`, or a per-token reason like `UNREGISTERED`.
