Dokumen ini menjelaskan cara mengintegrasikan dan menyesuaikan SDK di aplikasi Android Anda.
Mulai
Headless Mobile SDK untuk Android memungkinkan Anda mengintegrasikan kemampuan pusat kontak CCAI Platform ke dalam UI Android bawaan Anda sendiri.
Daripada menampilkan widget bermerek CCAI Platform, Anda:
Tambahkan modul CCAI Android SDK sebagai dependensi.
Buat layar, alur, dan desain visual Anda sendiri di Kotlin (direkomendasikan) atau Java.
Gunakan SDK untuk:
Mulai dan kelola sesi chat dan suara.
Menawarkan opsi email, panggilan suara, dan pengalihan.
Mendukung tindakan smart, lampiran, dan alur pasca-sesi (CSAT, survei, agen virtual).
CCAI Platform menangani logika pusat kontak (perutean, antrean, saluran, konfigurasi, pelaporan). Anda memiliki seluruh pengalaman aplikasi (UI, alur, dan branding).
Jika Anda lebih memilih UI bawaan dengan tema yang dapat dikonfigurasi, gunakan SDK seluler standar.
Persyaratan dan lingkungan yang didukung
Bagian ini menjelaskan persyaratan dan lingkungan yang didukung untuk Headless Mobile SDK for Android.
Persyaratan platform Android
Persyaratan platform berikut berlaku untuk Android:
Versi Android minimum: Android 6.0 (level API 23) atau yang lebih baru
Compile SDK: 36 (direkomendasikan)
Bahasa yang didukung: Kotlin (direkomendasikan) atau Java
Kompatibilitas Java: Java 17+
Gradle / Android Studio: versi plugin Android Gradle dan Android Studio terbaru yang kompatibel dengan aplikasi Anda dan rilis SDK yang Anda gunakan
Versi Kotlin: 1.6.0 atau yang lebih baru
Persyaratan instance CCAI Platform
Anda memerlukan akses ke setelan Developer instance CCAI Platform untuk mendapatkan:
Kunci perusahaan
Kode rahasia perusahaan
URL Host — nama host untuk platform CCAI (misalnya, your_subdomain.ccaiplatform.com)
Nilai ini digunakan untuk:
Kunci perusahaan dan URL Host — di aplikasi Android Anda untuk melakukan inisialisasi SDK.
Kode rahasia perusahaan — di backend Anda untuk menandatangani Token Web JSON (JWT) yang digunakan untuk mengautentikasi pengguna.
Jaringan dan izin
Aplikasi Anda harus mengizinkan traffic keluar ke endpoint CCAI Platform dan endpoint penyedia suara yang telah Anda konfigurasi.
Izin Android umum mencakup (daftar sebenarnya dapat bervariasi menurut versi SDK dan set fitur Anda):
Status internet / jaringan: untuk semua komunikasi SDK.
Mikrofon: untuk panggilan suara.
Notifikasi: untuk notifikasi push Firebase Cloud Messaging (FCM).
Penyimpanan / media: untuk lampiran.
Kamera: untuk pengambilan foto atau video dalam tindakan smart.
Screenshot: untuk berbagi layar (
MediaProjection).
Deklarasikan dan minta izin runtime sesuai dengan panduan Android OS.
Notifikasi push
Headless Android SDK menggunakan FCM untuk mengirimkan:
Notifikasi panggilan masuk.
Pesan terkait panggilan dan tindakan pintar tertentu.
Update untuk membantu mempertahankan status saat aplikasi berada di latar belakang.
Anda akan memerlukan:
Project Firebase.
google-services.json yang valid di modul aplikasi Anda.
Penanganan dan pendaftaran token FCM di aplikasi Anda.
UI dalam panggilan dan notifikasi kustom di aplikasi Anda.
Cara kerja Android SDK headless di aplikasi Anda
Headless Mobile SDK for Android dapat dilihat sebagai tiga lapisan:
Platform dan SDK CCAI Platform (ditangani oleh CCAI Platform)
SDK berinteraksi dengan aman dengan platform CCAI Platform dan menyediakan:
Autentikasi menggunakan Token Web JSON (JWT).
Metadata perutean saluran dan antrean (chat, panggilan suara, email, link pengalihan eksternal).
Pengelolaan status sesi real-time menggunakan objek layanan (
chatService,queueMenuService, dan lainnya).Pipeline transportasi yang aman untuk tindakan smart, lampiran file, dan berbagi layar.
Logika pengalihan dan evaluasi hierarki pasca-sesi.
Aplikasi Android Anda (UI dan logika - ditangani oleh Anda)
Anda mengontrol seluruh pengalaman visual dan navigasi:
Titik entri: misalnya, tab Bantuan atau tombol Hubungi kami.
Menu: cara Anda menampilkan antrean (misalnya, Penagihan, Dukungan teknis).
UI dalam sesi: balon chat, layar panggilan, dan kontrol kustom Anda.
Tindakan yang dilakukan aplikasi Anda: memanggil API layanan SDK untuk memulai dan mengakhiri sesi, mengamati peristiwa SDK menggunakan Kotlin Coroutines dan Flow, serta mendorong navigasi komponen.
Konfigurasi Admin Portal CCAI Platform
Admin CCAI Platform Anda mengonfigurasi aturan interaksi (jam operasional, saluran yang tersedia, batas waktu tunggu, dan survei). SDK membaca konfigurasi ini dan mengeksposnya ke aplikasi Anda sebagai data dan peristiwa mentah. Anda yang memutuskan cara menggambar konfigurasi tersebut di layar.
Mengambil kredensial perusahaan
Sebelum mengintegrasikan SDK, dapatkan kredensial dari instance Platform CCAI Anda:
Login ke Portal Admin Platform CCAI dengan akun administrator.
Buka Setelan > Setelan developer.
Di bagian Kunci perusahaan & kode rahasia, salin:
Kunci perusahaan
Kode rahasia perusahaan
Catat URL Host Anda — nama host untuk platform CCAI (misalnya,
your_subdomain.ccaiplatform.com).
Anda akan menggunakan:
Di aplikasi Android Anda: Kunci perusahaan dan URL host.
Di server backend Anda: Kode rahasia perusahaan untuk menandatangani JWT bagi autentikasi pengguna akhir dan data serta konteks kustom opsional yang digunakan oleh Platform CCAI.
Menambahkan SDK ke aplikasi Android Anda
Headless SDK menggunakan arsitektur modular. Anda menginstal CCAIKit inti
bersama modul fitur tertentu yang diperlukan aplikasi Anda (misalnya,
CCAIChat atau CCAIScreenShare).
Tambahkan repositori Maven CCAI
Tambahkan repositori Maven CCAI ke settings.gradle.kts project Anda (atau build.gradle root):
// settings.gradle.kts
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url = uri("https://sdk.ujet.co/ccaip/android/") }
}
}
Mengonfigurasi katalog versi Gradle (direkomendasikan)
Google Cloud merekomendasikan penggunaan katalog versi Gradle untuk mengelola dependensi SDK. Tambahkan kode berikut ke gradle/libs.versions.toml Anda:
[versions]
ccaiVersion = "3.3.1"
[libraries]
ccai-kit = { group = "com.ccaiplatform.android", name = "CCAIKit", version.ref = "ccaiVersion" }
ccai-chat = { group = "com.ccaiplatform.android", name = "CCAIChat", version.ref = "ccaiVersion" }
ccai-chat-red = { group = "com.ccaiplatform.android", name = "CCAIChatRed", version.ref = "ccaiVersion" }
ccai-call = { group = "com.ccaiplatform.android", name = "CCAICall", version.ref = "ccaiVersion" }
ccai-call-red = { group = "com.ccaiplatform.android", name = "CCAICallRed", version.ref = "ccaiVersion" }
ccai-screenshare = { group = "com.ccaiplatform.android", name = "CCAIScreenShare", version.ref = "ccaiVersion" }
Menambahkan dependensi
Di build.gradle.kts level aplikasi, tambahkan SDK inti dan modul fitur
tertentu:
// app/build.gradle.kts
android {
compileSdk = 36
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
dependencies {
// 1. Core (always required)
implementation(libs.ccai.kit)
// 2. Chat (required for chat sessions)
implementation(libs.ccai.chat)
implementation(libs.ccai.chat.red) // media layer paired with CCAIChat
// 3. Voice (required for instant calls, voicemail, and scheduled calls)
implementation(libs.ccai.call)
implementation(libs.ccai.call.red) // media/transport layer paired with CCAICall
// 4. Screen Share (optional)
// implementation(libs.ccai.screenshare)
}
Jika tidak menggunakan katalog versi, Anda dapat mendeklarasikan dependensi secara langsung:
val ccaiVersion = "3.3.1"
dependencies {
implementation("com.ccaiplatform.android:CCAIKit:$ccaiVersion")
implementation("com.ccaiplatform.android:CCAIChat:$ccaiVersion")
implementation("com.ccaiplatform.android:CCAIChatRed:$ccaiVersion")
implementation("com.ccaiplatform.android:CCAICall:$ccaiVersion") // Voice calls
implementation("com.ccaiplatform.android:CCAICallRed:$ccaiVersion") // Twilio VoIP backend
implementation("com.ccaiplatform.android:CCAIScreenShare:$ccaiVersion") // Optional, for screen share
}
Inisialisasi dan penyiapan
Lakukan inisialisasi SDK selama peluncuran aplikasi. Karena arsitektur modular SDK, lakukan inisialisasi sistem CCAI Platform inti terlebih dahulu, lalu daftarkan penyedia channel tertentu (seperti chat atau screen share).
Menerapkan antarmuka CCAIDelegate
SDK menggunakan antarmuka CCAIDelegate untuk callback autentikasi. Metode
utama adalah fungsi penangguhan Kotlin ccaiShouldAuthenticate() yang dipanggil SDK
saat memerlukan JWT.
import com.ccaiplatform.ccaikit.CCAIDelegate
class MyCCAIDelegate : CCAIDelegate {
/**
* Called by the SDK when it needs a signed JWT for authentication.
* This is a suspend function - you can make network calls here.
*
* @return The auth token returned by `authService.authenticate(jwt)`,
* or null on failure. This is what the SDK expects - not the raw JWT.
*/
override suspend fun ccaiShouldAuthenticate(): String? {
return try {
// 1. Call your backend server to get a signed JWT
val jwt = MyBackendApi.getSignedJwt() ?: return null
// 2. Exchange the JWT for an auth token using authService - this is
// what the SDK expects to be returned (not the raw JWT).
CCAI.authService?.authenticate(jwt)
} catch (e: Exception) {
null // Return null to signal authentication failure
}
}
}
Cuplikan sebelumnya menunjukkan alur dua langkah minimal (masuk → autentikasi → kembali).
Lihat Mengautentikasi pengguna akhir dan meneruskan data kustom untuk mengetahui kontrak autentikasi lengkap, termasuk:
- cara menandatangani JWT di backend Anda,
- cara
authenticate(jwt)menukarkannya dengan token autentikasi, - penyimpanan dan pembatalan validitas token dalam cache, dan
- contoh penggunaan dengan penanganan error.
Menginisialisasi SDK di class aplikasi Anda
Lakukan inisialisasi SDK di class aplikasi kustom Anda menggunakan objek singleton CCAI:
import android.app.Application
import com.ccaiplatform.ccaikit.CCAI
import com.ccaiplatform.ccaikit.InitOptions
import com.ccaiplatform.ccaichat.initializeChat
import com.ccaiplatform.ccaichat.model.ChatOptions
import com.ccaiplatform.ccaicall.initializeCall
import com.ccaiplatform.ccaikit.initializeScreenShare
import com.ccaiplatform.ccaikit.models.screenShare.ScreenShareOptions
class MainApplication : Application() {
private val delegate = MyCCAIDelegate()
override fun onCreate() {
super.onCreate()
// 1. Build InitOptions
val initOptions = InitOptions(
key = "YOUR_COMPANY_KEY",
urlHost = "your_subdomain.ccaiplatform.com",
languageCode = "en", // Optional: ISO 639 code
delegate = delegate // Your delegate implementation
)
// 2. Initialize the core SDK
CCAI.initialize(
context = this,
options = initOptions
)
// 3. Initialize chat (minimal)
CCAI.initializeChat(context = this)
// Initialize chat (with optional configuration)
// val chatOptions = ChatOptions(
// webFormInterface = null, // Implement to intercept and render custom web forms within your own UI
// downloadTranscriptVisibility = DownloadTranscriptVisibility.SHOW_ALL,
// greeting = "Hello! How can I help you?"
// )
// CCAI.initializeChat(
// context = this,
// options = chatOptions
// )
// 4. Initialize call (required whenever your app uses voice or scheduled calls)
CCAI.initializeCall(context = this)
// 5. Initialize screen share (optional)
// CCAI.initializeScreenShare(
// context = this,
// options = ScreenShareOptions(
// key = "YOUR_COMPANY_KEY",
// domain = "your_subdomain.ccaiplatform.com"
// )
// )
}
}
Referensi konfigurasi InitOptions
data class InitOptions(
/// The company key used for authentication
var key: String,
/// The host URL for CCAI platform (for example, "my-unique-instance.uc1.ccaiplatform.com")
var urlHost: String,
/// The preferred language code for localization (defaults to "en")
var languageCode: String? = "en",
/// Listener that handles authentication
var delegate: CCAIDelegate? = null,
/// Whether to cache the authentication token (defaults to true)
var cacheAuthToken: Boolean = true
)
Update AndroidManifest.xml
Pastikan class aplikasi kustom Anda terdaftar:
<application
android:name=".MainApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.YourApp">
</application>
Layanan SDK yang tersedia
Setelah inisialisasi, Anda dapat mengakses berbagai layanan melalui objek singleton CCAI:
val authService = CCAI.authService
val companyService = CCAI.companyService
val queueMenuService = CCAI.queueMenuService
val optionsService = CCAI.optionsService
val languageService = CCAI.languageService
val pushNotificationService = CCAI.pushNotificationService
val chatService = CCAI.chatService // Only available after initializeChat()
val screenShareService = CCAI.screenShareService // Only available after initializeScreenShare()
val rateService = CCAI.rateService // For CSAT ratings and survey submission
val callService = CCAI.callService // Only available after initializeCall()
Mengambil konfigurasi perusahaan
Setelah inisialisasi, Anda dapat mengambil konfigurasi tingkat perusahaan menggunakan
companyService. Hal ini berguna untuk mengisi pemilih bahasa, menampilkan nama perusahaan, atau membaca detail kontak dukungan sebelum pengguna masuk ke antrean.
// Fetch company details
val company = CCAI.companyService?.get()
// CompanyResponse contains:
// - displayName: String
// - supportEmail: String?
// - languages: List<String>
// - phoneNumber: String?
// ...
Mengautentikasi pengguna akhir dan meneruskan data kustom
Headless Mobile SDK untuk Android menggunakan token web JSON (JWT) untuk mengautentikasi pengguna dan meneruskan informasi kontekstual dengan aman ke CRM agen.
Cara kerjanya
SDK menggunakan alur autentikasi asinkron dua langkah yang disederhanakan:
SDK menentukan bahwa SDK perlu mengautentikasi pengguna.
Blok kode ini memanggil metode
CCAIDelegateAnda -ccaiShouldAuthenticate()- yang merupakan fungsi penangguhan.Aplikasi Anda menandatangani JWT dari jarak jauh di server backend menggunakan `Company
Aplikasi Anda menandatangani JWT dari jarak jauh di server backend menggunakan
Company Secret CodeAnda.Kemudian, aplikasi Anda meneruskan JWT yang ditandatangani ke
CCAI.authService?.authenticate(jwt)untuk menukarnya dengan token autentikasi.Token autentikasi ditampilkan ke SDK untuk menyelesaikan koneksi.
Menerapkan CCAIDelegate untuk autentikasi
Aplikasi Anda harus menerapkan antarmuka CCAIDelegate. SDK memanggil metode penangguhan
pertama saat memerlukan autentikasi.
Antarmuka CCAIDelegate
interface CCAIDelegate {
suspend fun ccaiShouldAuthenticate(): String?
}
Contoh penerapan (Kotlin)
class CCAIDelegate : CCAIDelegate {
override suspend fun ccaiShouldAuthenticate(): String? {
// 1. Sign JWT remotely on your backend server
val jwt = signJWTRemotely() ?: return null
// 2. Authenticate JWT using authService to get an auth token
return try {
CCAI.authService?.authenticate(jwt)
} catch (e: Exception) {
null
}
}
}
Contoh lengkap dengan penandatanganan JWT (hanya untuk referensi dan pengujian)
class AuthController : CCAIDelegate {
override suspend fun ccaiShouldAuthenticate(): String? {
// First, sign JWT with company secret (do this on your backend in production)
val jwt = Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS384, companySecret?.encodeToByteArray())
.compact()
// Then authenticate JWT using authService to get an auth token
return try {
CCAI.authService?.authenticate(jwt)
} catch (e: Exception) {
null
}
}
}
Meneruskan data kustom ke CRM
Jika Anda ingin meneruskan data kontekstual ke agen (misalnya, OS perangkat, lokasi, atau tingkat akun pengguna saat ini), backend Anda harus menyisipkan objek custom_data ke dalam payload JWT sebelum menandatanganinya.
Setiap bagian data kustom harus diformat sebagai objek JSON yang berisi
label (apa yang dilihat agen), nilai, dan jenis.
Jenis data yang didukung
string: teks standar (misalnya, "Pixel 8 Pro").number: bilangan bulat atau float (misalnya, 1234 atau 99.99).date: stempel waktu Unix UTC 13 digit termasuk milidetik (misalnya, 1537399655992).url: format URL HTTP/HTTPS standar.boolean: nilai benar atau salah standar.
Visibilitas agen: Anda dapat secara opsional meneruskan data ke platform CCAI
yang tersembunyi dari agen manusia, tetapi tersedia untuk perutean atau
analisis backend. Untuk melakukannya, sertakan "invisible_to_agent": true dalam
objek data.
Kunci CRM yang dicadangkan
Platform CCAI mendukung kunci khusus yang dicadangkan yang memicu perilaku bawaan di platform, seperti menandai pengguna sebagai VIP atau memperingatkan agen tentang pihak tidak bertanggung jawab. Data ini harus diformat sebagai jenis boolean dan hanya akan
diterima jika payload ditandatangani menggunakan metode JWT yang aman.
reserved_verified_customer: menunjukkan apakah pelanggan telah berhasil diautentikasi oleh sistem internal Anda.reserved_bad_actor: menandai pengguna ke agen sebagai calon spammer atau akun palsu.reserved_repeat_customer: menunjukkan apakah pelanggan ini sering menghubungi dukungan baru-baru ini.
Contoh payload dengan kunci yang dicadangkan
{
"iat": 1537399656,
"exp": 1537400256,
"custom_data": {
"reserved_verified_customer": {
"label": "Verified Customer",
"value": true,
"type": "boolean"
},
"reserved_bad_actor": {
"label": "Bad Actor",
"value": false,
"type": "boolean"
},
"reserved_repeat_customer": {
"label": "Repeat Customer",
"value": false,
"type": "boolean"
}
}
}
Mengelola token autentikasi
SDK menyediakan metode untuk memperbarui atau menghapus token autentikasi yang di-cache secara manual:
// Set a new auth token
CCAI.authService?.updateAuthToken("new_auth_token")
// Clear the current token (for example, on user logout)
CCAI.authService?.updateAuthToken(null)
Skema payload JWT data kustom
Saat backend Anda membuat payload akhir yang akan ditandatangani dengan Company
Secret Code Anda, payload tersebut harus mengikuti skema ini secara ketat. Perhatikan stempel waktu iat
(dikeluarkan pada) dan exp (masa berlaku) yang wajib ada.
{
"iat": 1537399656,
"exp": 1537400256,
"custom_data": {
"os_version": {
"label": "OS Version",
"value": "14.0",
"type": "string"
},
"membership_tier": {
"label": "Membership Tier",
"value": "Platinum",
"type": "string"
},
"ssn_last_four": {
"label": "SSN",
"value": "1234",
"type": "string",
"invisible_to_agent": true
},
"reserved_verified_customer": {
"label": "Verified Customer",
"value": true,
"type": "boolean"
}
}
}
Mengaktifkan notifikasi push
SDK menggunakan notifikasi push untuk:
Panggilan masuk.
Tindakan smart dan peristiwa terkait panggilan tertentu.
Mempertahankan status saat aplikasi berada di latar belakang.
Penyiapan Firebase
Buat atau gunakan project Firebase yang ada.
Daftarkan aplikasi Android Anda dan download file
google-services.json.Tempatkan
google-services.jsondi direktori modul aplikasi Anda.Di
build.gradle.ktstingkat root, tambahkan plugin layanan Google:// build.gradle.kts (Project) plugins { id("com.google.gms.google-services") version "4.4.2" apply false }Di
build.gradle.ktstingkat aplikasi, terapkan plugin dan tambahkan dependensiFirebase:// app/build.gradle.kts plugins { id("com.google.gms.google-services") } dependencies { // Firebase BoM for version management implementation(platform("com.google.firebase:firebase-bom:33.5.1")) implementation("com.google.firebase:firebase-messaging") }Sinkronkan project.
Mendaftarkan token FCM dengan SDK
Daftarkan token push FCM melalui pushNotificationService dan teruskan payload data FCM yang masuk ke SDK. Aplikasi Anda bertanggung jawab untuk merender notifikasi yang ditampilkan kepada pelanggan atau UI dalam panggilan.
Terapkan onMessageReceived
Jika Anda menggunakan FCM, terapkan pemroses di class FirebaseMessagingService untuk notifikasi push. Jika tidak diterapkan, layanan tidak akan
berfungsi dengan baik.
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.ccaiplatform.ccaikit.CCAI
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class MyFirebaseMessagingService : FirebaseMessagingService() {
private val scope = CoroutineScope(Dispatchers.IO)
override fun onMessageReceived(remoteMessage: RemoteMessage) {
scope.launch {
// Forward CCAI platform push notifications to the SDK.
CCAI.pushNotificationService?.handlePushNotification(remoteMessage.data)
// Render any customer-facing notification UI in your own app code.
MyNotificationRenderer.showIfNeeded(application, remoteMessage.data)
}
}
}
Terapkan onNewToken
Terapkan juga metode onNewToken untuk menangani update token. Hal ini memastikan
bahwa Headless Mobile SDK untuk Android menerima token notifikasi push terbaru:
class MyFirebaseMessagingService : FirebaseMessagingService() {
// ...
override fun onNewToken(token: String) {
// Fetch the updated token from Firebase and update it in CCAI
CCAI.pushNotificationService?.updatePushToken(token)
}
}
Daftarkan layanan di AndroidManifest.xml
Tambahkan Firebase Messaging Service ke AndroidManifest.xml Anda agar sistem dapat mengirimkan pesan push ke layanan Anda:
<application>
<service
android:name=".firebase.MyFirebaseMessagingService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
Pendaftaran token awal
Saat aplikasi dimulai (setelah inisialisasi SDK), daftarkan token FCM saat ini secara proaktif:
import com.google.firebase.messaging.FirebaseMessaging
// In your Application.onCreate(), after CCAI.initialize()
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
if (task.isSuccessful) {
val token = task.result
CCAI.pushNotificationService?.updatePushToken(token)
}
}
Penanganan izin notifikasi (Android 13+)
Di Android 13 (level API 33) dan yang lebih tinggi, aplikasi yang disebutkan di atas harus meminta izin runtime POST_NOTIFICATIONS. SDK menyediakan utilitas bawaan untuk
tindakan ini:
import com.ccaiplatform.ccaikit.util.PermissionUtil
// Request notification permissions from the user
PermissionUtil.requestPermissionsForNotifications(activity)
// Check if permissions have been granted
val isGranted = PermissionUtil.isPermissionsForNotificationsGranted(context)
if (isGranted) {
Log.d("CCAI", "Push notifications permitted")
}
Panggil fungsi ini lebih awal dalam siklus proses aplikasi Anda (misalnya, selama proses aktivasi atau peluncuran pertama) sebelum mendaftarkan token FCM, sehingga notifikasi push dapat dikirimkan.