故障排查
排查常见 Android、Supabase、RevenueCat、FCM 和发布问题。
把这一页当作 symptom-to-fix index 使用。如果问题属于更深的 setup page,先应用快速修复,再跳到相关页面。
Gradle sync 失败
| 现象 | 可能原因 | 修复 |
|---|---|---|
| Android Gradle plugin error | Android Studio 或 Gradle tooling 太旧 | 使用 Android Studio Meerkat+ 后重新 sync |
| JDK mismatch | Android Studio 指向旧 JDK | 把 Gradle JDK 设置为 17 或更新 |
| KSP 或 Kotlin source-set errors | 版本 pins 被改动 | 保持 Kotlin 2.3.0、AGP 9.2.1、KSP 2.3.9 对齐 |
| Ktor duplicate/version errors | Supabase/Ktor pins 漂移 | 保持 supabase-kt 3.2.6,direct Ktor OkHttp engine 3.3.1 |
在模板根目录验证:
./gradlew assembleDebuglocal.properties keys 没生效
Gradle 会在 configuration 阶段把 local.properties 读入 BuildConfig fields。修改 keys 后,请重新构建 app:
./gradlew clean assembleDebug常见检查:
| 检查 | 修复 |
|---|---|
| File path | local.properties 必须在 repo root,和 settings.gradle.kts 同级 |
| Key spelling | 使用 Configuration 页面中的精确名称 |
| Quoting | 使用原始值,不要加 shell-style quotes |
| Release signing | RELEASE_STORE_FILE 相对 repo root |
| App Links | 修改 LINKING_DOMAIN 后需要重装 app 才能刷新 manifest data |
Supabase auth callback 卡住
Email verification、OTP、password reset 和 OAuth callbacks 都需要在 Supabase Auth settings 中配置 redirect URL:
soar://auth-callback如果浏览器打开了但 app 没有恢复,还要确认 app 已安装,并且没有其他 app 抢占相同 custom scheme。
Google Sign-In 按钮不显示
GOOGLE_WEB_CLIENT_ID 为空时,按钮会被隐藏。
| 问题 | 修复 |
|---|---|
| 粘贴了 Android client id | 使用 Google OAuth web client id |
| SHA fingerprints 缺失 | 在 Google Cloud / Firebase 注册 debug 和 release SHA-1/SHA-256 fingerprints |
| 运行中改了 key | 编辑 local.properties 后重新 build 并 reinstall |
| Supabase provider 未启用 | 在 Supabase Auth providers 中启用 Google |
登录后 Todos 或 Profile 失败
模板 repo 当前附带 device_tokens、subscriptions 和 payments migrations,但没有附带 todos 与 profiles migrations。Supabase Setup 页面已经补了缺失 SQL。
| 现象 | 修复 |
|---|---|
relation "todos" does not exist | 应用 Supabase Setup 中内联的 todos SQL |
relation "profiles" does not exist | 应用 Supabase Setup 中内联的 profiles SQL |
| 读取其他用户为空 | 预期行为:RLS scoped 到当前登录用户 |
| Delete-account 留下 auth user | 当前代码的预期行为;发布前增加服务端删除函数 |
FCM token 为空或收不到 push
| 现象 | 可能原因 | 修复 |
|---|---|---|
| Emulator 上没有 token | Emulator image 没有 Play services | 使用 Play-services emulator image 或真机 |
| Build 没读取 Firebase config | 缺少 app/google-services.json | 从 Firebase 下载并放到 app/ |
| 通知权限被拒绝 | Android 13+ runtime permission 未授权 | 打开 Permissions 或系统设置并授权通知 |
| Test push unauthorized | 缺少 Supabase session 或 Edge JWT | 调用 send-test-push 前先登录 |
| Function 无法发送 | Firebase Admin secret 缺失 | 设置 FIREBASE_SERVICE_ACCOUNT_JSON 或 split Firebase secrets |
send-test-push 不接受 body 里的 raw device token。它会通过 RLS 读取当前登录用户的 device_tokens rows,只发送 Android/FCM tokens。
RevenueCat offering 为空
| 原因 | 修复 |
|---|---|
| App 不在 Play testing track | 上传 internal testing build,并通过 Play 安装 |
| Products inactive | 在 Play Console 激活 pro_monthly、pro_yearly、pro_lifetime |
| Package name mismatch | RevenueCat 和 Play 必须匹配 app 的 applicationId |
| SDK key 错误 | 把 Android public SDK key 设置为 REVENUECAT_ANDROID_KEY |
| Tester 未授权 | 把账号加入 Google Play license testers |
如果购买成功但 Pro 未解锁,请检查 RevenueCat webhook delivery 和 public.subscriptions row。
In-App Updates 或 Review 不触发
这些是 Play-only APIs。Android Studio debug install 可以验证 app 不崩溃,但行为不会等同于 Play-delivered build。
| Surface | 测试路径 |
|---|---|
| In-App Updates | 从 internal testing track 安装,再上传更高 versionCode |
| In-App Review | 从 Play 安装,并满足 app 的 trigger/cooldown logic |
| Update fallback URL | Listing 创建后,把 APP_UPDATE_URL 设置为 Play listing |
首个版本建议让 MIN_APP_VERSION 和 LATEST_APP_VERSION 等于当前 versionName,避免 app 一上线就反复提示更新。
Deep links 打不开 app
| Link type | 检查 |
|---|---|
soar://... | App 已安装、scheme 未被其他 app 抢占、route 存在于 DeepLinkResolver |
| HTTPS App Links | LINKING_DOMAIN 已设置、app 已重装、assetlinks.json 使用 release SHA-256 托管 |
| Auth callback | 使用 soar://auth-callback;它由 Supabase 接管,DeepLinkHandler 会跳过 |
用下面命令测试 custom-scheme route:
adb shell am start -a android.intent.action.VIEW -d "soar://refer"Instrumented tests 跑不起来
connectedDebugAndroidTest 需要已连接设备或正在运行的 emulator:
./gradlew connectedDebugAndroidTest如果 tests 卡在 biometric 或 Play-services surfaces,请使用匹配功能需求的 emulator image,并在每轮之间清理 app data。
