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

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

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.
  • Deregister on logout: POST /api/universal/device/deregister with { appId, appToken, deviceId } — a hard, idempotent delete (Device Registration).

4. Send and verify

// 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 (deviceId) — FCM's answer is immediate: accepted, or a per-token reason like UNREGISTERED.