PushEngage — Android Spoke
You're working in an Android app. This skill walks the customer through integrating PushEngage from zero to verified test push, or debugs a broken integration.
Routing
| Customer intent | Read this file next |
|---|---|
| "Integrate PushEngage" / "Set up PushEngage" (greenfield or partial) | This file's "Integration flow" section below. |
| "PushEngage isn't working" / specific symptom | Hand off to pushengage-debug/SKILL.md (skill: pushengage-debug). |
| "Audit my PushEngage setup" | Read audit-checks.md and run the checks. |
| Concept / terminology question | Read ../pushengage/concepts.md. |
| Best practices / rule lookup | Read best-practices.md (Android-specific) or ../pushengage/best-practices.md (cross-platform). |
| API surface / "does method X exist" | Read version-matrix.md first; if not listed, fetch only URLs from references.md. |
Integration flow (greenfield)
This is the happy path. Follow the parts strictly in order — earlier artifacts feed later steps.
Part 1 — Discovery & prereqs
Before touching anything, gather:
- SDK levels — read
compileSdk,minSdkVersion,targetSdkVersionfromapp/build.gradleorapp/build.gradle.kts. - Gradle DSL — Groovy (
build.gradle) vs Kotlin (build.gradle.kts). The install template differs. - UI framework — Compose vs classic Views. Grep
androidx.composeinapp/build.gradle*; if present, flag the Compose sub-flow (Part 3c). - Existing Application subclass — grep for
extends Application/: Application()underapp/src/main/. If one exists, init code extends it; if not, we create one and register it inAndroidManifest.xml. - MainActivity base class — plain
ActivityvsAppCompatActivityvsComponentActivity(Compose). This affects which permission-flow snippet applies. - Account state — ask the customer:
- Do you already have a Firebase project for this app?
- Do you already have a PushEngage account + site for this app?
- Compose guidance — if Compose was auto-detected in step 3, confirm with the customer ("I see Jetpack Compose in your build file — apply the Compose-specific snippets in Part 3c?").
Output a one-paragraph integration plan in chat. Wait for the customer to confirm before any edits.
Part 2 — Firebase + dashboard (out-of-code, before any code edits)
Counter-intuitive but right: do these BEFORE editing code. The dashboard's App ID is needed for setAppId(...); Firebase project + Service Account upload have real-world setup steps in the Firebase console.
- Read
firebase-setup.md. Walk the customer through creating (or reusing) the Firebase project, adding the Android app with the correctapplicationId, downloadinggoogle-services.json, and generating a Service Account JSON. Capture:google-services.jsonfile path inside the customer's repo (typicallyapp/google-services.json) — the file lives with the customer.- Service Account JSON file path on the customer's machine — NEVER ask the customer to paste the JSON contents in chat. They upload it directly to the PushEngage dashboard.
- Sender ID and
applicationIdfor cross-checking later.
- Read
dashboard-setup.md. Walk the customer through Site Settings → Installation → Android SDK and through Service Account JSON upload. Capture: App ID UUID (ask the customer to paste this in chat — it is a public identifier, not a secret).
Do not proceed to Part 3 until both steps confirm.
Part 3 — In-code edits
3a — Install
Read install.md. Pick the Groovy DSL or Kotlin DSL template per the detection from Part 1.
- Auto-edit + announce posture for config files: root
build.gradle*,app/build.gradle*,settings.gradle*,AndroidManifest.xml, and placement ofgoogle-services.json. Show the diff in chat, then apply. - Apply the Google Services plugin, Firebase BoM (if absent), and the PushEngage Android SDK dependency.
- Add the
<uses-permission>entries toAndroidManifest.xml, including an explicitPOST_NOTIFICATIONSentry iftargetSdkVersion >= 33. (The SDK's own library manifest already declaresPOST_NOTIFICATIONSand manifest merger propagates it — the explicit app-level entry is for clarity, not correctness.) - Run a Gradle sync (or instruct the customer to) and confirm success before moving on.
3b — Application class init code
Read init-code.md. Pick the template by language (Kotlin vs Java) and by whether an Application subclass already exists.
- If no
Applicationsubclass exists: create one (e.g.,MyApp.kt) and register it viaandroid:name=".MyApp"inAndroidManifest.xml(auto-edit + announce for the manifest). - If one exists: extend it — do not replace it.
Diff + confirm posture for Application class edits. Show the proposed diff. Ask the customer "apply?" before writing.
Insert the App ID UUID captured in Part 2 into the setAppId(...) call. Per XP-BP-01, leave a comment recommending the customer move it to BuildConfig / resources later.
3c — Jetpack Compose deltas (Compose-only)
Run this sub-step only if Compose was detected in Part 1.
Read jetpack-compose.md. Apply Compose-specific deltas:
- Permission request via
rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission())instead ofActivityCompat.requestPermissions. - Where to invoke the PushEngage permission helper from a
Composable(typically inside aLaunchedEffector a button click handler). ComponentActivityis the expected base class — confirm against what was detected in Part 1.
Diff + confirm for any edits inside a Composable file the customer authored.
3d — Runtime permission flow
Read permission-flow.md. Pick the snippet for the customer's MainActivity base class (AppCompatActivity / ComponentActivity) and targetSdkVersion (Android 13+ needs the runtime POST_NOTIFICATIONS request; below 13 the permission is granted at install time but you still call PushEngage's subscriber registration).
Diff + confirm posture for MainActivity edits.
Per XP-BP-03, prompt for permission at a meaningful moment, not immediately on onCreate. Suggest the right call site; do not force onCreate.
Part 4 — Verification
The success criterion is a real test notification reaches the customer's device.
- Customer connects a real device with Google Play Services — NOT an emulator without GMS. FCM will not deliver to a GMS-less image.
- Customer installs and launches the app once → grants the notification permission when prompted (Android 13+).
- Customer goes to PushEngage dashboard → Campaign → Push Broadcasts → Create New Push Broadcast → fills minimal fields → sends to the test device (or to "All Subscribers" if it's the only one).
- Ask the customer: "Did the notification arrive?"
If yes → go to Part 5.
If no → hand off to pushengage-debug/SKILL.md with the symptom "test push didn't arrive."
Part 5 — Post-integration best-practices nudge
Single short message. Don't auto-apply; list rule IDs and one-line summaries — pick 2–3 that are actually relevant to what you just integrated. Examples:
- XP-BP-01: move the App ID UUID out of source into
BuildConfigor a resource (you currently have it hardcoded). - XP-BP-03: request notification permission at a meaningful user moment, not on launch.
- XP-BP-07: gate
enableLoggingbehindBuildConfig.DEBUG. - ANDROID-BP-04: set a proper monochrome notification icon — Android renders a white/silhouette bell if you ship
ic_launcheras the small icon. - ANDROID-BP-05: create named notification channels at app start (Android 8+) so users can manage categories.
- ANDROID-BP-13: warn the customer about OEM background restrictions (Xiaomi, Oppo, Vivo, Huawei) and link them to the audit check.
(Customize the list to what you actually saw in the customer's code — don't dump all of them if some don't apply.)
Debugging entry points
If the customer says any of the following — or if Part 4 verification fails — invoke pushengage-debug/SKILL.md:
- "Notifications aren't arriving"
- "Permission prompt never shows" / "I denied it once and now I can't re-prompt"
- "Notifications work for a while then stop" → strong OEM background-restriction signal (Xiaomi / Oppo / Vivo / Huawei / OnePlus)
- "Notification icon is wrong" / "shows a white square or a bell"
- "Build fails" (Gradle sync, manifest merger, duplicate class, etc.)
- "App force-closes on launch after install" (often an
Applicationinit order issue or missinggoogle-services.json) - "Subscriber count looks wrong" / "I'm not registering as a subscriber"
- "Deep link from notification doesn't open the right screen"
The debug skill handles audit + known-issues + symptom tree.
What you must not do
- Don't invent PushEngage method names. If you're not sure a method exists on the Android SDK, check
version-matrix.md. If still unsure, fetch an allowlisted URL fromreferences.md. If still unsure, say so — don't guess. - Don't auto-edit the customer's
Applicationsubclass orMainActivitywithout showing the diff and getting confirmation. Entry-point code is diff + confirm. Config files (build.gradle*,AndroidManifest.xml,settings.gradle*) are auto-edit + announce. - Don't touch files outside the integration scope. No refactoring, no Kotlin/Java migrations, no Gradle version bumps that weren't required, no formatting passes.
- Don't fetch URLs not in
references.md. The allowlist exists so the customer can trust where you got information. - Don't ask the customer for Service Account JSON contents in chat. It is a secret. They upload the file directly to the PushEngage dashboard; you only need to know the local path and confirm the upload succeeded.