Status: Living — Google Cloud Console runbook; Android sync stays inert until these steps are done.
The Android counterpart to sync-icloud-setup.md.
GoogleDriveSyncTransport (core/sync/transport/google_drive_sync_transport.dart)
stores blobs in the app’s hidden AppData folder via the Drive API. Until
the Google Cloud OAuth clients below exist and the web client ID is wired in
(see step 4), sign-in fails gracefully and the transport stays in
SyncSignedOut (no-op) — so the code ships safely without this, it just
doesn’t do anything yet.
Two OAuth clients are needed, because the app doesn’t ship a
google-services.json:
google_sign_in as
serverClientId (required on Android for authenticate(); see the plugin’s
README). The web client ID is not a secret — it’s embedded in every
shipped app — so it’s fine to put in a build flag / CI variable.https://www.googleapis.com/auth/drive.appdata (the
hidden per-app folder — not the broad Drive scope).atomhess@gmail.com (the project’s personal account) at minimum.OAuth 2.0 Client IDs (APIs & Services → Credentials → Create credentials → OAuth client ID). Create both:
a. Android client
dev.tomhess.crosscueflutter run on a device/emulator — already known):
6B:25:E8:37:4C:F0:0E:82:1F:10:A0:82:A8:57:D2:BA:4E:F9:73:5C
(Regenerate any time with:
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android)
keytool -list -v -keystore <release.jks> -alias <alias>.)b. Web application client
serverClientId for step 4. It
looks like 1234567890-abc...def.apps.googleusercontent.com.Wire the web client ID into the app (serverClientId)
The transport reads it from a compile-time define
GOOGLE_OAUTH_SERVER_CLIENT_ID (empty → inert). Supply it at build time:
flutter run --dart-define=GOOGLE_OAUTH_SERVER_CLIENT_ID=<web-client-id>
GOOGLE_OAUTH_SERVER_CLIENT_ID
(GitHub → repo → Settings → Secrets and variables → Actions → Variables).
release.yml already passes it to both the APK and AAB builds.drive.appdata only. The AppData folder is invisible in the user’s
Drive UI and isolated per app — the same trust model as the iCloud container.GoogleDriveSyncTransport.signIn()) is wired: the
orchestrator’s enable() calls it, and the Settings/onboarding toggle drives
the Google prompt (#157). It needs both OAuth clients above plus the
serverClientId define; missing any of them makes authenticate() fail (the
Android Credential Manager often reports this as a “canceled” error), and the
transport stays inert.google-services.json is required — google_sign_in matches the Android
client by package name + SHA-1, and uses the web client ID only as the
serverClientId.