@shardev/capacitor-google-auth
v1.0.5
Published
Capacitor plugin for native Google sign-in using GoogleSignIn on iOS and Google Sign-In (play-services-auth) on Android
Maintainers
Readme
@shardev/capacitor-google-auth
Capacitor plugin for native Google sign-in on iOS and Android. It wraps the official
GoogleSignIn SDK on iOS and
Google Sign-In for Android
(play-services-auth) on Android.
- Interactive sign-in with the Google account picker
- Silent restore of a previous sign-in (cached tokens)
- ID token for verifying the user on your backend
- Sign-out and full disconnect (revoke granted scopes)
Supported platforms
| Platform | Library | Minimum version |
| -------- | ------- | --------------- |
| iOS | GoogleSignIn 9.x (CocoaPods GoogleSignIn) | iOS 13+ |
| Android | Google Sign-In 21.6.x (Maven com.google.android.gms:play-services-auth) | Android 7.0 (API 24) |
Web/PWA is not supported because native Google sign-in requires GoogleSignIn; calling any
method other than initialize() on the web rejects with NOT_IMPLEMENTED.
Installation
npm install @shardev/capacitor-google-auth
npx cap syncPrerequisites
1. Create OAuth credentials in Google Cloud Console
Open the Google Cloud Console and select (or create) the project that owns your app.
Go to APIs & Services → Credentials → Create Credentials → OAuth client ID.
Create two clients:
| Client type | Purpose | | ---------------------- | ----------------------------------------------------------------------- | | Web application | Android: the web client ID is passed to
requestIdTokenand signs the ID token. Also used by your backend to exchange tokens. | | iOS | iOS: the client ID identifies your app to Google. Configured with your bundle identifier. |Optionally, if your app is distributed on Android, also create an Android client with your package name and the SHA-1 fingerprint of your signing certificate (use the same
keytoolcommand as below).Copy the Web client ID and the iOS client ID.
2. Register the Android package and SHA-1 (Android only)
Google verifies your app's package name and signing certificate fingerprint when it returns the ID token. In the Android OAuth client:
keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v | grep SHA1Add the SHA-1 of the certificate signing your app (the debug keystore for development, your release keystore for production).
3. (Optional) Add google-services.json
Not required, because this plugin passes the web client ID programmatically. If your app
already uses Firebase or you prefer Google's default wiring, download
google-services.json from the Firebase console and drop it into android/app/.
Platform setup
iOS
Podfile
npx cap sync adds the pod automatically. Verify your ios/App/Podfile contains:
pod 'ShardevCapacitorGoogleAuth', :path => '../node_modules/@shardev/capacitor-google-auth'The GoogleSignIn pod is pulled in automatically.
Info.plist
Register the reversed client ID as a URL scheme so the sign-in flow can return to your
app. Replace <REVERSED_CLIENT_ID> with your iOS client ID reversed (for example
com.googleusercontent.apps.1234567890-abcdef) and add to ios/App/App/Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.1234567890-abcdef</string>
</array>
</dict>
</array>No AppDelegate changes are required. The modern sign-in flow uses an in-process
ASWebAuthenticationSessionand delivers its callback directly. The plugin only forwards Capacitor's URL-open notification to cover the Google Device Policy flow.
Android
No manifest changes are required: play-services-auth declares its own sign-in activity.
You only need the package name + SHA-1 registered in Google Cloud Console (see above).
Note: Google has deprecated the classic
GoogleSignInAPI (auth.api.signin) in favor of Google Identity Services (auth.api.identity). The classic API remains fully functional and is what this plugin uses, because it is the only one that exposes the user's email, granted scopes, and server auth code. Both APIs ship inside the sameplay-services-authartifact. If you need a forward-looking migration path, see https://developers.google.com/identity/sign-in/android.
Minimum SDK
play-services-auth requires minSdkVersion 21. Ensure android/app/build.gradle (or
your variables.gradle) sets it:
minSdkVersion 24Usage
import { GoogleAuth } from '@shardev/capacitor-google-auth';
async function signIn() {
// 1. Initialize once at app startup (or before the first sign-in).
await GoogleAuth.initialize({
// Android: web client ID. iOS: iOS client ID.
clientId: '1234567890-abcdef.apps.googleusercontent.com',
// Web client ID, used to sign the ID token. Required on Android.
serverClientId: '1234567890-abcdef.apps.googleusercontent.com',
// Optional defaults (openid/profile/email are always granted).
scopes: ['https://www.googleapis.com/auth/drive.readonly'],
// Optional: restrict to a Google Workspace domain.
// hostedDomain: 'your-company.com',
});
// 2. Restore the session silently.
const { account } = await GoogleAuth.getCurrentUser();
// 3. Sign in interactively if there is no account.
let result = account
? await GoogleAuth.getToken()
: await GoogleAuth.login();
console.log(result.idToken, result.account.email);
// 4. Send the ID token to your backend.
// Verify it against your web client ID:
// https://developers.google.com/identity/sign-in/web/backend-auth
// 5. Sign out (keeps granted scopes), or disconnect to revoke them.
await GoogleAuth.logout();
// await GoogleAuth.disconnect();
}Verifying the ID token on your backend
The idToken returned by login()/getToken() is a Google-signed JWT for your web
client ID. Verify it server-side using Google's official libraries
(Java,
Node.js,
Go/Python/PHP) and read
the user's profile from the sub, email, name, picture claims.
API
initialize(options)
Configures GoogleSignIn. Call it once before any other method.
| Option | Type | Default | Description |
| ------------------------ | ---------- | ----------------------------- | ---------------------------------------------------------------------- |
| clientId | string | – (required) | Android: web client ID. iOS: iOS client ID. |
| serverClientId | string | clientId on Android | Web client ID used to sign the ID token (the requestIdToken target). |
| scopes | string[] | ['openid', 'profile', 'email'] | Default scopes for login(). Default scopes are always granted. |
| hostedDomain | string | – | Restrict sign-in to a Google Workspace domain, e.g. your-company.com.|
| requestServerAuthCode | boolean | false | Android only: request a server auth code for exchanging on your backend. |
login(options?)
Interactive Google sign-in with the account picker.
| Option | Type | Description |
| -------- | ---------- | -------------------------------------------------- |
| scopes | string[] | Additional scopes to request (default scopes are always granted). |
| hint | string | iOS only: hint for the account (usually the email). |
Returns Promise<LoginResult>.
getToken()
Silently restores the previous sign-in and returns fresh tokens. Fails with NO_ACCOUNT
when the user has never signed in (call login() then).
getCurrentUser()
Returns Promise<{ account: GoogleAccount | null }> with the currently signed-in user,
or null.
logout()
Signs the current user out on the device. The user can sign in again without re-consenting to previously granted scopes.
disconnect()
Signs the user out and revokes all OAuth scopes granted to the app. The next sign-in will ask for consent again.
Types
interface LoginResult {
accessToken: string; // Android: ID token. iOS: OAuth access token.
idToken: string; // Google ID token for your web client ID.
serverAuthCode?: string;
expiresOn?: number; // UNIX timestamp in milliseconds (iOS only)
scopes: string[];
account: GoogleAccount;
}
interface GoogleAccount {
id: string;
email: string;
name: string;
givenName: string;
familyName: string;
photoUrl?: string;
idToken?: string;
accessToken?: string;
serverAuthCode?: string;
grantedScopes: string[];
}Error codes
| Code | Description |
| ----------------------- | ------------------------------------------------------------------------ |
| NOT_INITIALIZED | A method other than initialize() was called first. |
| INVALID_ARGUMENT | Missing or invalid options (e.g. clientId). |
| USER_CANCELLED | The user cancelled the sign-in flow. |
| NO_ACCOUNT | No previous sign-in available for a silent request. |
| NO_VIEW_CONTROLLER | iOS: no view controller was available to present the flow. |
| SIGN_IN_FAILED | Android: the sign-in intent failed (status code in the error message). |
| INTERACTION_REQUIRED | Android: silent sign-in failed; call login() to prompt the user. |
| NOT_IMPLEMENTED | The method is not available on the web. |
| UNEXPECTED | The native flow completed without a result. |
| SDK error code / AUTH_ERROR | Any other failure; the native error code and message are forwarded. |
How it works
- Android:
GoogleSignInOptionsis built programmatically withrequestIdToken(serverClientId)(plus optional scopes, hosted domain, and server auth code) and passed toGoogleSignIn.getClient(...). Interactive sign-in launchesgetSignInIntent()through Capacitor's activity-result API; silent restore usesclient.silentSignIn(). - iOS:
GIDConfigurationis assigned toGIDSignIn.sharedInstance. Interactive sign-in usessignIn(withPresenting:); silent restore usesrestorePreviousSignIn. No AppDelegate changes are needed.
Contributing
npm install
npm run verify # typechecks and builds the TypeScript/rollup outputLicense
MIT
