惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
F
Fortinet All Blogs
云风的 BLOG
云风的 BLOG
MyScale Blog
MyScale Blog
D
DataBreaches.Net
Stack Overflow Blog
Stack Overflow Blog
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC
The GitHub Blog
The GitHub Blog
Jina AI
Jina AI
B
Blog RSS Feed
I
InfoQ
N
Netflix TechBlog - Medium
T
The Blog of Author Tim Ferriss
Microsoft Azure Blog
Microsoft Azure Blog
Recent Announcements
Recent Announcements
GbyAI
GbyAI
H
Help Net Security
L
LangChain Blog
M
MIT News - Artificial intelligence
Y
Y Combinator Blog
aimingoo的专栏
aimingoo的专栏

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
I Built a Free, Modern Alternative to Paid Universal Sign...
Sagnikpal · 2026-05-19 · via DEV Community

If you've tried adding Google sign-in to a React Native app recently, you've probably ended up at @react-native-google-signin/google-signin.

It is the de-facto standard. It works. It also has a paid Universal Sign-In tier that uses Google's modern Credential Manager APIs on Android, while the free tier still wraps the older legacy Sign-In SDK.

That paywall is fair. The maintainers have built and maintained a serious package. But for many teams — indie developers, side projects, MVPs, and Android-first Expo apps — the gap still hurts.

So I built expo-google-credential-auth: an MIT-licensed, Android-first package built on the modern Credential Manager + Google Identity Services stack.

This is the comparison I wish existed when I was choosing between the available options.

Who this is for

TL;DR

  • Use paid Universal Sign-In if you need iOS today, SLA support, passkeys, or broader federated identity support.
  • Use expo-google-credential-auth if you're Android-first, want the modern Google auth stack for free, and prefer a smaller dependency you can audit end-to-end.

Use the paid Universal Sign-In product if you need iOS today, enterprise support, or passkey / federated sign-in flows beyond Google. It is a mature commercial product and a sensible choice for production apps that need full coverage immediately.

Use expo-google-credential-auth if you're shipping Android first, want the modern Credential Manager stack without a license fee, want a small dependency you can read end-to-end, and can wait for iOS and web support.

Both options rely on modern Google APIs on Android. The real question is not which one is universally better. It is which one fits your product right now.

Comparison table

Feature google-signin free google-signin paid expo-google-credential-auth
Android SDK Legacy Google Sign-In SDK Modern Credential Manager Modern Credential Manager
iOS support ✅ Yes ✅ Yes 🟡 Coming soon
Web support Separate flow ✅ Yes 🟡 Coming soon
License MIT Commercial MIT
Auth and authorization separation Conflated into one call Conflated into one call Explicit separate flows
Cancellation handling Throws exception Throws exception Returns discriminated union
Revoke clears Play Services caches Partial Yes Yes
Native code auditability Large codebase Large codebase + closed paid bits Small focused Kotlin module
Bundle impact Larger Larger Smaller focused module
Support model Community / paid tier Commercial SLA GitHub issues, best effort

A table alone does not explain the trade-offs. These are the four differences that matter most in practice.

1. Authentication and authorization should be separate flows

This is the design decision I care about most.

Many Google sign-in integrations blur two different OAuth concepts into one signIn() call. That call often returns an idToken and sometimes an accessToken, which encourages developers to treat them as interchangeable.

They are not interchangeable.

Concept Authentication Authorization
Question answered Who is this user? What can my app do on their behalf?
Token type ID token Access token
Typical use Verify user identity on your backend Call Google APIs
Revocable? No, it expires naturally Yes
User interface Account picker Consent screen

Common bug: the /userinfo 401 usually happens when an app sends an ID token to an endpoint that expects an access token.

In expo-google-credential-auth, authentication and authorization are separate calls:

// Authentication — for your backend
const { idToken, user } = await GoogleAuth.signIn();

Enter fullscreen mode Exit fullscreen mode

// Authorization — for Google APIs
const { accessToken } = await GoogleAuth.requestAuthorization({
  scopes: ['https://www.googleapis.com/auth/drive.readonly'],
});

Enter fullscreen mode Exit fullscreen mode

This means you can:

  • sign in without requesting API permissions,
  • request additional scopes later,
  • revoke API access without signing the user out,
  • model your app flow closer to the OAuth protocol underneath.

2. Cancellation is not an error

In many existing integrations, dismissing the sign-in sheet throws an exception:

try {
  await GoogleSignin.signIn();
} catch (e) {
  if (e.code === statusCodes.SIGN_IN_CANCELLED) {
    // Not actually an error
  } else if (e.code === statusCodes.NO_SAVED_CREDENTIAL_FOUND) {
    // Also not really an error
  } else {
    // Actual failure
  }
}

Enter fullscreen mode Exit fullscreen mode

A user closing a sheet is not exceptional. It is a normal branch in the user flow.

expo-google-credential-auth models this as a discriminated union:

const result = await GoogleAuth.signIn();

switch (result.type) {
  case 'success':
    return handleUser(result.idToken, result.user);

  case 'cancelled':
    return;

  case 'noSavedCredentialFound':
    return promptCreateAccount();
}

Enter fullscreen mode Exit fullscreen mode

Actual failures, such as network errors or configuration problems, can still throw. But normal user behavior stays in the return type, where TypeScript can narrow it properly.

3. Android revoke behavior needs more than one cleanup step

Most teams do not notice this until production: revoking access on the server is not always enough to clear local Android auth state.

A complete Android revoke flow needs to handle multiple layers:

  1. Server-side revocation

    Call Google's revoke endpoint to invalidate the grant.

  2. Credential Manager state

    Clear Credential Manager's local credential state.

  3. Play Services OAuth cache

    Clear sign-in and revoke state through Google Play Services APIs.

  4. Android AccountManager token cache

    Invalidate the underlying Android OAuth token cache.

Each cleanup step should be best-effort and isolated. If one layer fails, the others should still run.

The implementation in expo-google-credential-auth is intentionally small and auditable. The point is not that the code is clever. The point is that the auth behavior is visible instead of hidden.

4. Small dependencies are easier to trust

This is more subjective, but it matters for auth libraries.

When authentication breaks, you want to understand the dependency. You want to trace what native code does. You want to audit the token flow. You want to know whether the package is doing something surprising.

expo-google-credential-auth is intentionally focused: a small Kotlin implementation with thin TypeScript bindings.

Small is a feature when the package sits on your login path.

When you should still pay

The paid Universal Sign-In tier is still the right choice if:

  • You need iOS in production today. expo-google-credential-auth is Android-first right now.
  • You need passkeys or non-Google federated identity. This package focuses only on Google auth.
  • You need commercial support or an SLA. GitHub issues are not a substitute for vendor support.
  • Your current setup already works. Migration risk is real. Do not rewrite working auth code for a marginal improvement.

This is not a "never pay" argument. It is a "choose the right trade-off" argument.

For many Android-first Expo apps, free + focused + modern is enough.

Try it

Install the package:

npm install expo-google-credential-auth

Enter fullscreen mode Exit fullscreen mode

You will need an Android development build because Credential Manager requires native code. It will not work inside Expo Go.

The setup guide and Android configuration notes are available in the npm README.

Final thoughts

Google sign-in in React Native has historically been harder than it should be, especially in Expo projects that want to use modern Android APIs without paying for a commercial tier.

expo-google-credential-auth is my attempt to make that path smaller, clearer, and free.

If you're building an Android-first Expo app and want modern Google auth without a license fee, try it and see whether it fits your project.


📦 Package: expo-google-credential-auth
💻 Source & issues: https://github.com/sagnik2001/expo-google-credential-auth

About me: I build mobile and developer tools. Find me on GitHub · LinkedIn.

If this post saved you time, a ⭐ on the repo or a follow here on Dev.to means a lot.