Android SDK
Native Android SDK (Kotlin/Java) for rich push (16 styles), in-app messages, identity, event tracking with offline flush, lifecycle signals, remote variables, and inbox. Package com.growwise:growwise-sdk:1.2.0 · minSdk 21.
Overview
GrowWise initializes device registration (guest_id), analytics + sessions, notification channels, FCM (GrowWiseFirebaseService), and in-app lifecycle tracking.
- Rich push notifications — 16 visual styles
- In-app messages — interstitial / cover, screen-targeted
- Identify users + traits; track events with SQLite offline cache
- Install / open / update / crash lifecycle signals
- Remote variables and inbox messages
Important FCM rule
Always send GrowWise campaigns in FCM’s data payload. Do not include a top-level notification block — Android may render the system notification and bypass rich SDK styles.
Prerequisites
- GrowWise / TheGrowise API key (gk_…)
- Firebase project with Cloud Messaging enabled
- google-services.json for your applicationId
- White notification icon drawable (e.g. ic_notification)
Add the SDK dependency
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.gms.google-services")
}
android {
defaultConfig {
minSdk = 21
targetSdk = 35
}
}
dependencies {
implementation("com.growwise:growwise-sdk:1.2.0")
implementation("com.google.firebase:firebase-messaging:24.1.0")
}dependencies {
implementation(files("libs/growwise-release.aar"))
implementation("com.google.firebase:firebase-messaging:24.1.0")
}Firebase setup
- Place google-services.json in the app module root
- Apply the Google Services plugin
- Ensure Firebase package name matches applicationId
Permissions
On Android 13+ (API 33+), request POST_NOTIFICATIONS at runtime.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.VIBRATE" />if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.POST_NOTIFICATIONS),
REQUEST_CODE_NOTIFICATIONS
)
}Initialize in Application.onCreate()
Initialize as early as possible so background pushes and analytics work.
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
val config = GrowWiseConfig.Builder(this)
.setApiKey("YOUR_API_KEY")
.setSmallIcon(R.drawable.ic_notification)
.setDefaultChannelId("growwise_default")
.setDefaultChannelName("General Notifications")
.setAutoCreateChannels(true)
.setLoggingEnabled(true) // disable in production
.setLogLevel(GrowWiseLogLevel.DEBUG)
.setAutoInitFcm(true)
.build()
GrowWise.initialize(this, config)
}
}<application
android:name=".MyApplication"
... >Identify users
GrowWise.logIn(
userId = "user_12345",
traits = mapOf(
"Name" to "Jane Doe",
"Email" to "jane@example.com",
"membership" to "Premium"
)
)
if (GrowWise.isLoggedIn()) { /* identified */ }
GrowWise.logout() // clears identity and rotates guest_idTrack events
Events cache in SQLite, flush in batches (~every 5 events), and flush when backgrounded. Default props: $os, $platform, $app_version, $lib_version.
- Automatic: app_install, App First Open, App Updated, app_open, notification_received, App Crashed
GrowWise.logEvent("app_opened")
GrowWise.logEvent(
"product_viewed",
mapOf(
"item_id" to "sku_1001",
"category" to "Electronics",
"price" to 199.99
)
)
GrowWise.track("checkout_started", mapOf("cart_value" to 499.0))Notification callbacks
GrowWise.setNotificationCallback(object : GrowWise.NotificationCallback {
override fun onNotificationDisplayed(notificationId: Int, payload: NotificationPayload) { }
override fun onNotificationClicked(payload: NotificationPayload) { }
override fun onNotificationDismissed(payload: NotificationPayload) { }
override fun onNotificationActionClicked(actionId: String, payload: NotificationPayload) { }
})Optional APIs
val token = GrowWise.getDeviceToken()
GrowWise.setPushToken(token ?: return)
GrowWise.setLocation(28.6139, 77.2090)
GrowWise.setOptOut(true)
GrowWise.fetchRemoteVariables("YOUR_PROJECT_ID") { success ->
if (success) {
val title = GrowWise.getRemoteVariableString("home_banner_title", "Welcome")
}
}
GrowWise.getInboxMessages { messages -> /* ... */ }
GrowWise.markInboxMessageRead("message_id")Custom FirebaseMessagingService
SDK ships GrowWiseFirebaseService. If you already have an FCM service, forward data messages.
class MyFirebaseService : FirebaseMessagingService() {
override fun onMessageReceived(message: RemoteMessage) {
val data = message.data
if (data.isNotEmpty()) {
val handled = GrowWise.handleFcmPayload(data)
if (!handled) { /* non-GrowWise */ }
}
}
override fun onNewToken(token: String) {
GrowWise.setPushToken(applicationContext, token)
}
}Config builder reference
- setApiKey(String) — required
- setSmallIcon(Int) — required status-bar icon
- setDefaultChannelId / setDefaultChannelName
- setAutoCreateChannels(Boolean) — default true
- setLoggingEnabled / setLogLevel
- setAutoInitFcm(Boolean) — default true
- setAppVersion / setLocation — optional
Push type values (data payload)
- BASIC, BIG_TEXT, BIG_PICTURE, INBOX, MEDIA, MESSAGING, PROGRESS
- CUSTOM_LAYOUT, ACTION_BUTTONS, DIRECT_REPLY, GROUPED
- HEADS_UP, TIMER, CALL, BUBBLE, SILENT
{
"to": "DEVICE_FCM_TOKEN",
"priority": "high",
"data": {
"type": "BASIC",
"title": "Hello from GrowWise",
"body": "This is a data-only push.",
"priority": "1"
}
}In-app payloads
Also delivered via FCM data. Types: INTERSTITIAL (modal), COVER (full screen). Optional targetActivity for screen targeting.
{
"data": {
"campaignId": "inapp_sale_modal",
"type": "INTERSTITIAL",
"title": "Exclusive offer",
"body": "Get 25% off with code GET25.",
"imageUrl": "https://cdn.example.com/offer.jpg",
"primaryButtonText": "Shop Now",
"primaryButtonAction": "myapp://promotions/get25",
"secondaryButtonText": "Maybe Later"
}
}Best practices
- Initialize in Application.onCreate
- logIn after auth; logout on sign-out
- Data-only FCM; priority: high for time-sensitive pushes
- White/alpha status-bar icon
- Disable verbose logging in production
- Request POST_NOTIFICATIONS on Android 13+
- Test on real devices (OEM behaviour differs)
Troubleshooting
- No notifications — permission, google-services.json, Logcat FCM
- Tray but no sound — channel muted; use priority high; clear app data
- Rich style missing — top-level FCM notification used; send data-only
- Events missing — wrong API key / opt-out / wait for flush
- adb logcat -s GrowWise:* FirebaseMessaging:*