Troubleshooting

Debug common Android, Supabase, RevenueCat, FCM, and release issues.

Use this page as a symptom-to-fix index. When a problem belongs to a deeper setup page, follow the related link after applying the quick fix.

Gradle sync fails

SymptomLikely causeFix
Android Gradle plugin errorAndroid Studio or Gradle tooling is too oldUse Android Studio Meerkat+ and sync again
JDK mismatchAndroid Studio points to an old JDKSet the Gradle JDK to 17 or newer
KSP or Kotlin source-set errorsVersion pins were changedKeep Kotlin 2.3.0, AGP 9.2.1, and KSP 2.3.9 aligned
Ktor duplicate/version errorsSupabase/Ktor pins driftedKeep supabase-kt on 3.2.6 and the direct Ktor OkHttp engine on 3.3.1

Verify from the template root:

./gradlew assembleDebug

local.properties keys do not apply

Gradle reads local.properties into BuildConfig fields during configuration. After changing keys, rebuild the app:

./gradlew clean assembleDebug

Common checks:

CheckFix
File pathlocal.properties must be in the repo root, next to settings.gradle.kts
Key spellingUse the exact names from the Configuration page
QuotingUse raw values, not shell-style quotes
Release signingRELEASE_STORE_FILE is relative to the repo root
App LinksLINKING_DOMAIN changes require reinstalling the app to refresh manifest data

Supabase auth callback stalls

Email verification, OTP, password reset, and OAuth callbacks require this redirect URL in Supabase Auth settings:

soar://auth-callback

If the browser opens but the app does not resume, also confirm the app is installed and that another app is not claiming the same custom scheme.

Google Sign-In button is missing

The button is hidden when GOOGLE_WEB_CLIENT_ID is empty.

ProblemFix
Android client id was pastedUse the Google OAuth web client id
SHA fingerprints missingRegister the debug and release SHA-1/SHA-256 fingerprints in Google Cloud / Firebase
Key changed while app was runningRebuild and reinstall after editing local.properties
Supabase provider disabledEnable Google in Supabase Auth providers

Todos or profile fail after sign-in

The template repo currently ships migrations for device_tokens, subscriptions, and payments, but not the todos and profiles migrations. The Supabase Setup page includes the missing SQL.

SymptomFix
relation "todos" does not existApply the inline todos SQL from Supabase Setup
relation "profiles" does not existApply the inline profiles SQL from Supabase Setup
Reads return empty for another userExpected: RLS is scoped to the signed-in user
Delete-account leaves auth userExpected with current code; add a server-side deletion function before release

FCM token is null or push does not arrive

SymptomLikely causeFix
No token on emulatorEmulator image lacks Play servicesUse a Play-services emulator image or real device
Build ignores Firebase configapp/google-services.json is missingDownload it from Firebase and place it in app/
Notification permission deniedAndroid 13+ runtime permission not grantedOpen Permissions or system settings and grant notifications
Test push returns unauthorizedMissing Supabase session or Edge JWTSign in before calling send-test-push
Function cannot sendFirebase Admin secret missingSet FIREBASE_SERVICE_ACCOUNT_JSON or the split Firebase secrets

send-test-push never accepts a raw device token in the body. It reads the signed-in user's device_tokens rows through RLS and sends only Android/FCM tokens.

RevenueCat offering is empty

CauseFix
App is not on a Play testing trackUpload an internal testing build and install through Play
Products are inactiveActivate pro_monthly, pro_yearly, and pro_lifetime in Play Console
Package name mismatchRevenueCat and Play must match the app's applicationId
Wrong SDK keySet the Android public SDK key as REVENUECAT_ANDROID_KEY
Tester not licensedAdd the account as a Google Play license tester

If purchase succeeds but Pro does not unlock, inspect the RevenueCat webhook delivery and the public.subscriptions row.

In-App Updates or Review do not trigger

These are Play-only APIs. Debug installs from Android Studio are useful for checking that the app does not crash, but they do not behave like a Play-delivered build.

SurfaceTest path
In-App UpdatesInstall from an internal testing track, then upload a higher versionCode
In-App ReviewInstall from Play and satisfy the app's trigger/cooldown logic
Update fallback URLSet APP_UPDATE_URL to the Play listing once it exists

Keep MIN_APP_VERSION and LATEST_APP_VERSION equal to the current versionName for the first release so the app does not immediately nag users.

Link typeChecks
soar://...App installed, scheme not claimed by another app, route exists in DeepLinkResolver
HTTPS App LinksLINKING_DOMAIN set, app reinstalled, assetlinks.json hosted with release SHA-256
Auth callbackUse soar://auth-callback; Supabase owns it and DeepLinkHandler skips it

Test a custom-scheme route with:

adb shell am start -a android.intent.action.VIEW -d "soar://refer"

Instrumented tests do not run

connectedDebugAndroidTest needs a connected device or running emulator:

./gradlew connectedDebugAndroidTest

If tests hang on biometric or Play-services surfaces, use an emulator image that matches the feature being exercised and clear app data between runs.

On this page