Why does Google sign in fail inside a native web view app?
Google refuses OAuth inside embedded web views and returns a disallowed-user-agent error. The flow has to leave the web view and run in the system browser, then return to the app. That is a shell behavior, not a Rails change, and it is why the magic-code sign-in is the primary path in the native apps.
Why Google does this
An embedded web view is controlled by the app hosting it, which means the app could read what the user types into Google's own page. Blocking it is a security decision on Google's side, it applies to every app regardless of framework, and it is not something your server can opt out of.
What has to happen instead
The shell intercepts the OAuth start, opens a system browser or an in-app browser tab, and handles
the return. On iOS that is ASWebAuthenticationSession; on Android it is Custom Tabs. Both are
purpose-built for this and both keep the session cookie in a way a plain browser launch does not.
That code lives in the shells under mobile/ios and mobile/android.
Magic codes do not have this problem
bin/dev
A six-digit code arrives by email and is typed into your own form, inside your own web view. Nothing is embedded, nothing is blocked, and no platform rule applies. It is the same flow on web and in the app.
This is the argument for passwordless being the primary path rather than a fallback: it is the one that works everywhere without a native detour.
Apple's version is different again
Sign in with Apple is iOS-only and expects the native sheet rather than a web flow. So the app can have a native Apple button and a magic code form, with Google either handled through a browser session or left off the app entirely. That last option is legitimate, and it is the least work.
Both providers stay optional
User.upsert_by_email! in app/models/user.rb is the single signup chokepoint, so someone who signs
in by code on the phone and by Google on the desktop lands in the same account. Which providers you
offer on which platform is a product decision, not an architectural one.
Check it on a device
The simulator and a real phone differ here. Test the sign-in path on hardware before you submit, because a broken sign-in is the one bug that stops review at the first screen.