이 문서는 데스크탑 AI Usage Dashboard에서 수집한 사용량 snapshot을 Android 위젯으로 동기화하는 방법을 설명합니다.
핵심 구조: 데스크탑 앱이 provider 사용량을 새로고침 → Cloudflare Relay에 안전한 snapshot 업로드 → 모바일 앱/위젯이 sync URL로 snapshot을 가져옴 → Android는 FCM wake signal + WorkManager polling으로 자동 갱신합니다.
Sync Widget 버튼을 누를 때정리하면, PC 서버/데스크탑 앱이 켜져 있고 refresh가 계속 돌면 모바일도 계속 따라옵니다. 단, FCM/Android 배터리 정책 때문에 완전한 실시간 보장은 아니며, polling fallback으로 eventual sync를 보장합니다.
git clone <repository-url>
cd ai-usage-dashboard
npm install
npm run typecheck
cargo check --manifest-path apps/desktop/src-tauri/Cargo.toml
개발 모드 실행은 실제 사용자 HOME을 명시하는 것이 안전합니다. provider credential은 보통 실제 사용자 홈 디렉터리에 있기 때문입니다.
HOME="$HOME" npm run dev:tauri
macOS에서 Hermes/자동화 환경 안에서 실행한다면 다음처럼 실제 계정 HOME을 명시하세요.
HOME=/Users/<you> npm run dev:tauri
com.aiusagedashboard.widget
google-services.json을 다운로드합니다.apps/android/app/google-services.json
주의:
google-services.json은 public repo에 커밋하지 마세요.com.google.gms.google-services plugin을 조건부로 적용합니다.Cloudflare relay는 데스크탑이 업로드한 snapshot을 모바일이 가져갈 수 있도록 보관합니다.
npm run deploy:relay:cf
배포 후 Worker base URL을 기록합니다.
https://<your-worker>.<your-account>.workers.dev
Firebase Console에서 service account JSON을 발급한 뒤, 값 자체를 코드나 문서에 넣지 말고 Cloudflare Worker secret으로만 등록합니다.
필요한 secret:
FCM_PROJECT_ID
FCM_CLIENT_EMAIL
FCM_PRIVATE_KEY
예시:
npx wrangler secret put FCM_PROJECT_ID
npx wrangler secret put FCM_CLIENT_EMAIL
npx wrangler secret put FCM_PRIVATE_KEY
주의:
npm run build:android
APK 위치:
apps/android/app/build/outputs/apk/debug/app-debug.apk
ADB 설치:
adb install -r apps/android/app/build/outputs/apk/debug/app-debug.apk
필요하면 downgrade 허용:
adb install -r -d apps/android/app/build/outputs/apk/debug/app-debug.apk
Settings로 이동합니다.System 섹션으로 이동합니다.Android widget sync를 켭니다.Relay URL에 Worker base URL을 입력합니다.https://<your-worker>.<your-account>.workers.dev
형태는 다음과 같습니다.
https://<your-worker>.<your-account>.workers.dev/v1/snapshots/<pairId>?token=<syncToken>
중요:
token=까지 포함된 전체 URL을 붙여넣어야 합니다.Sync Widget을 누릅니다.Desktop app
refreshes provider usage
builds sanitized snapshot
PUT /v1/snapshots/:pairId Authorization: Bearer <syncToken>
Cloudflare relay
stores latest sanitized snapshot
sends wake-only FCM message when snapshot etag changes
Android app/widget
receives wake signal
enqueues WidgetSyncWorker one-shot
GET /v1/snapshots/:pairId?token=<syncToken>
stores snapshot in SharedPreferences
refreshes home-screen widget
FCM payload에는 provider 사용량, sync URL, sync token이 들어가지 않습니다. push는 단지 “새 snapshot이 있으니 fetch해라”라는 wake signal입니다.
Sync Widget을 한 번 수동으로 눌러 저장된 URL을 확인하세요.token= 값이 포함되어 있는지 확인하세요./v1/snapshots/... 형태인지 확인하세요.HOME=/Users/<you> npm run dev:tauri
google-services.json이 Android 앱 경로에 있는지 확인하세요.com.aiusagedashboard.widget인지 확인하세요.FCM_PROJECT_ID, FCM_CLIENT_EMAIL, FCM_PRIVATE_KEY secret이 등록되어 있는지 확인하세요.처음에는 데스크탑 앱이 한 번 provider refresh와 snapshot upload를 해야 합니다. 데스크탑 앱에서 Android widget sync를 켠 뒤 provider refresh를 실행하세요.
google-services.json을 public repo에 커밋하지 않았습니다.wrangler secret put으로만 등록했습니다.token=<syncToken> 같은 placeholder만 사용했습니다.