Kembo
BlogDocsSign in
Kembo

Mobile auth in minutes. Google and Apple sign-in for Expo, Flutter, Capacitor, and Web.

Product

  • Documentation
  • Blog
  • Pricing
  • Get started

Legal

  • Privacy Policy
  • Terms of Service
  • DPA
  • Data Deletion

© 2026 Kembo

Operated by ByteStronauts

← All posts
July 11, 2026·9 min read

Google sign-in on mobile: OAuth clients, SHA fingerprints, and redirect URIs explained

redirect_uri_mismatch. Error 10. DEVELOPER_ERROR. Google sign-in on mobile fails in ways that make no sense until you understand OAuth client types, SHA-1 fingerprints, and Play App Signing. Here is the mental model that makes all of it click.

Google sign-inOAuthAndroidiOSExpomobile auth

Almost everyone who wires up Google sign-in on mobile hits the same wall: it works perfectly in the browser, then fails on a real Android device with a cryptic DEVELOPER_ERROR or Error 10, or on the web with redirect_uri_mismatch. The error messages are useless because the actual problem is conceptual — Google's OAuth setup assumes you understand client types, fingerprints, and signing keys, and nobody explains them in order.

This post gives you that mental model. Once you see how the pieces fit, every Google sign-in error becomes a quick diagnosis instead of an afternoon of guessing.

There is no such thing as "a" Google client

The first misconception: people create one OAuth client and try to use it everywhere. Google issues different client types, and each platform must use the right one.

  • Web client. Has a client secret and a list of authorized redirect URIs. Used for web flows — and, importantly, it is often the client whose ID your backend uses to verify the ID token, even for native logins.
  • Android client. No secret. Identified by your package name plus a SHA-1 fingerprint of the signing key. No redirect URIs.
  • iOS client. No secret. Identified by your bundle ID, with a reversed-client-ID URL scheme registered in the app.

Mixing these up is the root cause of most failures. A redirect URI belongs on the web client, not the Android one. A SHA-1 belongs on the Android client, not the web one.

SHA-1 fingerprints: the Android gotcha

On Android, Google does not trust a package name alone — anyone could claim it. It trusts the combination of your package name and the SHA-1 fingerprint of the certificate that signed the APK. If the fingerprint registered in Google Cloud does not match the one that signed the build on the device, you get DEVELOPER_ERROR and no further explanation.

The trap is that you have more than one signing key:

  • Debug key. Auto-generated on your machine. Builds you run locally are signed with it, so its SHA-1 must be registered for dev to work.
  • Release/upload key. The key you sign your store uploads with. Different fingerprint — register it too.
  • Play App Signing key. The big one. If you use Play App Signing (most apps do), Google re-signs your app with a key they hold. The version users download is signed with the App Signing key, whose SHA-1 lives in the Play Console. Forget this and sign-in works in testing but breaks for real users from the store.

The classic "works in dev, fails in production" bug

You registered your debug and upload fingerprints, tested everything, shipped — and Google sign-in is broken for downloaded users. The cause is almost always the missing Play App SigningSHA-1. Copy it from the Play Console's App Integrity page into your Google Cloud Android client and it lights up.

Redirect URIs: the web and Expo gotcha

redirect_uri_mismatchmeans the exact callback URL your app sent does not appear in the web client's list of authorized redirect URIs. "Exact" is literal: scheme, host, port, path, and trailing slash all count. http vs https, localhost vs 127.0.0.1, and a stray slash are all enough to fail.

On Expo and other native frameworks that use a web-style flow, your redirect is often a custom scheme or a proxy URL. Whatever it is, it has to be registered verbatim. Log the redirect URI your app actually generates and paste that — do not type it from memory.

The consent screen will block you eventually

Two more things catch teams late:

  • Testing vs production.While your OAuth consent screen is in "Testing," only the test users you list can sign in. Everyone else gets access denied. Publish the consent screen before launch.
  • Verification. If you request sensitive scopes, Google may require app verification, which takes time. For plain sign-in you usually only need basic profile and email, which avoids the heavy review — another reason to keep your scopes minimal.

A debugging checklist

  1. DEVELOPER_ERROR / Error 10 on Android? SHA-1 mismatch. Check debug, upload, and Play App Signing fingerprints against your package name.
  2. redirect_uri_mismatch? Log the actual redirect URI and add it verbatim to the web client.
  3. Access denied for some users? Consent screen still in testing, or they are not on the test-user list.
  4. Token verification fails on the backend?You are probably checking against the wrong client ID — server verification typically expects the web client's audience.

How Kembo removes the whole class of bugs

None of this is your product. It is OAuth bookkeeping that every team rediscovers the hard way. Kembo hosts Google sign-in so the fingerprint and redirect dance happens once, on our side, and verifies the resulting tokens correctly before handing you a clean signed-in user.

  • You drop in AuthView and get a working Google button on iOS, Android, and web — no per-platform client juggling in your app.
  • Token verification, audience checks, and session creation happen server-side, so a misconfigured client ID is not your problem to debug.
  • The same project also gives you Sign in with Apple, so you satisfy Apple's 4.8 requirement at the same time.

Minimal scopes, fewer headaches

Whether you self-host or use Kembo, ask for the least you need — usually just the user's basic profile and email. Smaller scopes mean no verification review, a cleaner consent screen, and an easier story on your Play Data safety form.

The model that makes it click

Google sign-in stops being mysterious once you hold one idea: the platform you are on determines the client type, the client type determines what identifies you (SHA-1 on Android, redirect URI on web, bundle ID on iOS), and the backend verifies against the right audience. Every error maps to one of those four things.

If you would rather not hold any of it in your head, start a free Kembo project and let the OAuth plumbing be ours. Next week: what happens after sign-in — sessions, refresh tokens, and secure storage.

Ready to skip the Wednesday OAuth panic? Create a free Kembo project.