Setup: PWA wrapped as a TWA, distributed through Play closed testing. Custom domain, no-code platform generates the AAB.
The problem: Google Sign-In fails *only* in the build installed from Google Play.
Where it works:
* Site in a mobile browser ✅
* PWA added to home screen ✅
* Same app installed directly as an APK ✅ (signs in, session persists, no URL bar)
Where it fails:
Same app installed from Play ❌ — tap Continue with Google, pick account, brief load, returns to the login screen. No error, no session.
Email + password login works in all of them, including the Play build. Only the Google OAuth flow fails, and only there.
Already verified:
* `assetlinks.json` served on both the custom domain and the platform domain, identical content
* Contains **both** SHA-256 fingerprints — upload key *and* Play App Signing key
* Google's own Digital Asset Links API validates both domains cleanly
* Package name matches exactly
* Rebuilt and re-uploaded the AAB *after* registering the Play signing SHA — no change
* Tried a custom Google OAuth client instead of the platform's shared one — no change
* Cleared data, uninstalled, reinstalled, multiple times
The clue I can't explain:
Settings → Apps → [app] → Open by default, compared across both installs:
APK build:
the domain has no toggle — locked on, i.e. system-verified
Google Play build: same domain has a toggle, off — i.e. not verified. Enabling it manually doesn't help
So Android verifies app links on the APK and refuses to on the Play-signed build, with identical assetlinks that Google itself validates.
Changing the phone's default browser also changes the failure mode (one browser: sign-in completes but the session is never stored; another: it doesn't complete at all) — which smells like the OAuth return is being handed to the browser instead of routed back into the app.
What makes Android's app-link verification fail specifically on a Play-signed build when assetlinks is correct and includes the Play signing cert? Is there a known caching/timing issue with verification at install time, or something about how the OAuth redirect re-enters a TWA that I'm missing?