Skip to main content

Google authentication

Google is the enabled provider in capacitor-auth-manager (3.x). The same call — auth.signIn(AuthProvider.GOOGLE) — dispatches natively to the right Google SDK on each platform and returns a Google credential containing an ID token or an access token, depending on the flow:

PlatformMechanismReturns
WebGoogle Identity ServicesOne-Tap: idToken; popup: accessToken
iOSGoogleSignInidToken + accessToken (+ serverAuthCode when serverClientId is set)
AndroidGoogleSignIn, Credential Manager fallbackidToken reliably (accessToken / serverAuthCode come from the separate Google Authorization API, not the sign-in call)

For Firebase, use GoogleAuthProvider.credential(idToken ?? null, accessToken ?? null) so both web flows work.

When you need a backend​

Sign-in completes with no backend required. Both web flows use Google Identity Services and need no client secret. You only involve a server if you opt into a serverAuthCode (iOS) and exchange it for refresh tokens — and that exchange must happen on your server, never in the browser.

Configuration​

Use the exported AuthProvider enum (recommended — typo-safe; the string 'google' also works).

import { auth, AuthProvider } from 'capacitor-auth-manager';

auth.configure({
providers: {
[AuthProvider.GOOGLE]: {
clientId: 'YOUR_WEB_OAUTH_CLIENT_ID', // web + Android serverClientId fallback
serverClientId: 'YOUR_WEB_OAUTH_CLIENT_ID', // REQUIRED on Android to receive an idToken
iosClientId: 'YOUR_IOS_OAUTH_CLIENT_ID', // iOS (or set GIDClientID in Info.plist)
webFlow: 'popup', // direct click; Firebase accepts access tokens
},
},
persistence: 'memory',
});

You can also set the Google options in capacitor.config under the plugin block instead of auth.configure.

Options (GoogleAuthOptions)​

OptionWherePurpose
clientIdweb (required), Android fallbackWeb OAuth client id; the id token's aud.
serverClientIdAndroid (required for idToken), iOSWeb OAuth client id; Google needs it to return an idToken.
iosClientIdiOSiOS OAuth client id (or set GIDClientID in Info.plist).
scopesallExtra OAuth scopes (default openid email profile).
hostedDomainallRestrict to a Google Workspace domain.
loginHintallPrefill an account.
filterByAuthorizedAccountsAndroidCredential Manager returning-user UX.
autoSelectEnabledAndroidOne-tap auto-select for returning users.
nonceweb, iOS, AndroidBind the request to an id-token nonce claim (validated).
webFlowweb'auto' (default: One-Tap, then the OAuth2 popup if One-Tap is not shown) · 'one-tap' · 'popup'. Also accepted per call in signIn({ options }).
androidFlowAndroid'auto' (default since 3.1.0: GoogleSignIn, then Credential Manager if it fails for any reason other than a cancel) · 'legacy' · 'credential-manager' · 'bottom-sheet' · 'button'. Also accepted per call.

Sign in​

const result = await auth.signIn(AuthProvider.GOOGLE);
const idToken = result.credential.idToken; // One-Tap (web), iOS, Android
const accessToken = result.credential.accessToken; // web popup fallback, iOS

Hand the credential to Firebase (identical on every platform)​

The package is Firebase-agnostic — it pulls in no firebase dependency. You feed the Google id token to Firebase yourself:

import { getAuth, GoogleAuthProvider, signInWithCredential } from 'firebase/auth';

const result = await auth.signIn(AuthProvider.GOOGLE);
const { idToken, accessToken } = result.credential;
await signInWithCredential(
getAuth(),
GoogleAuthProvider.credential(idToken ?? null, accessToken),
);

What you get back​

signIn resolves to an AuthResult:

{
user: { uid, email, emailVerified, displayName, photoURL, providerData: [...], metadata: {...} },
credential: {
providerId: 'google.com',
signInMethod: 'google.com',
idToken?: string, // web One-Tap, iOS, Android
accessToken?: string, // web popup and iOS; not returned by Android sign-in
serverAuthCode?: string, // iOS when serverClientId + offline access; exchange on YOUR server only
},
}

Per-platform token availability (honest):

  • Web (GIS): One-Tap returns an idToken; the OAuth2 popup fallback returns an accessToken (and the Google profile). Firebase accepts either — GoogleAuthProvider.credential(idToken ?? null, accessToken). See Web platform.
  • iOS (GoogleSignIn): idToken + accessToken (+ serverAuthCode when serverClientId is set).
  • Android (GoogleSignIn, Credential Manager fallback): returns idToken — from GoogleSignIn's account chooser, or from Credential Manager when GoogleSignIn fails (androidFlow: 'auto'). accessToken / serverAuthCode require the separate Google Authorization API and are not returned by the sign-in call (planned).

For the complete React/Firebase bootstrap, Firebase session ownership, and failure handling, use the AI integration guide.

Native setup​

Android​

  1. In Google Cloud / Firebase, create an Android OAuth client and add every signing SHA-1/SHA-256 (debug, upload and Play App Signing); create (or reuse) a Web OAuth client.
  2. Pass that Web client id as serverClientId; Google returns no idToken without it.
  3. No google-services.json is needed by this plugin — it uses no Firebase native SDK. Google needs only the registered fingerprint and the Web client id.
  4. The default flow shows GoogleSignIn's account chooser (which can add an account) and falls back to Credential Manager. See Android platform.

The plugin declares only INTERNET; no SMS, contacts or biometric permissions are added to your manifest.

iOS​

  1. Create an iOS OAuth client in Google Cloud.
  2. Add GIDClientID (your iOS client id) to Info.plist, or pass it as iosClientId.
  3. Add the reversed client id as a URL scheme in Info.plist → CFBundleURLTypes (e.g. com.googleusercontent.apps.XXXX).
  4. For a serverAuthCode, also set serverClientId (your Web client id).

Migrating from @codetrix-studio/capacitor-google-auth​

// before
await GoogleAuth.initialize({ clientId });
const u = await GoogleAuth.signIn();
await signInWithCredential(getAuth(), GoogleAuthProvider.credential(u.authentication.idToken));

// after
import { auth, AuthProvider } from 'capacitor-auth-manager';
auth.configure({ providers: { [AuthProvider.GOOGLE]: { clientId, serverClientId, iosClientId } } });
const res = await auth.signIn(AuthProvider.GOOGLE);
await signInWithCredential(getAuth(), GoogleAuthProvider.credential(res.credential.idToken ?? null, res.credential.accessToken ?? null));

The id token moves from result.authentication.idToken to result.credential.idToken. Use both credential fields in Firebase handoff because the web popup returns an access token.

Security & storage​

  • No secrets are persisted by default. Short-lived id tokens are re-derived from the Google SDK's silent restore rather than written to localStorage / @capacitor/preferences. Storage adapters hold profile/session metadata, not bearer credentials. Android tokens are memory-only; the iOS Google SDK owns its Keychain session.
  • Both GIS web flows require no client secret. A serverAuthCode (iOS) must be exchanged on your server, never in the browser.
  • The package does not verify id-token signatures in the browser — validate the id token server-side (or via Firebase) before trusting its claims.

Notes & caveats​

  • Web Google sign-in tries One-Tap / FedCM first and falls back to the OAuth2 popup by default (webFlow: 'auto'). A dismissed One-Tap rejects with USER_CANCELLED; a closed popup with POPUP_CLOSED_BY_USER. Google's branded button is available via renderButton(element) on the web provider class — it is not a method on the auth singleton, so reach it with import { GoogleAuthProviderWeb } from 'capacitor-auth-manager/providers/web' and construct the provider yourself.
  • Native consumers compile in package CI. Validate a new version in one app (web + one Android device + one iOS device) before rolling it out widely.