Per aggiungere Google Sign-In a un'app Capacitor, crea un client ID OAuth Web, uno iOS e uno o più Android in Google Cloud, installa @capgo/capacitor-social-login, chiama SocialLogin.initialize({ google: { webClientId, iOSClientId } }), poi SocialLogin.login({ provider: 'google' }). Android utilizza Credential Manager di Google, iOS usa SDK di Google Sign-In e il web usa Google Identity Services. Tutti e tre restituiscono un ID token da verificare sul tuo server.
Questa guida illustra ogni passaggio per Capacitor 8 nell'ottobre 2026, incluse le parti che di solito causano problemi: impronte SHA-1, la chiave Play App Signing e lo schema URL di iOS.
Come funziona il Google Sign-In in un'app Capacitor
| Piattaforma | API nativo utilizzato dal plugin | Client ID passato al plugin | Altra configurazione della console |
|---|---|---|---|
| Android | Credential Manager (androidx.credentials) |
Web client ID come webClientId |
Client Android con package name e SHA-1 |
| iOS | Google Sign-In SDK | iOS client ID come iOSClientId |
URL scheme client ID invertito in Info.plist |
| Web | Google Identity Services | Web client ID come webClientId |
Origini JavaScript autorizzate |
Google blocca OAuth all'interno di WebViews incorporate con disallowed_useragent errore, ed è per questo che caricare la pagina di accesso di Google nella tua WebView Capacitor non funziona. Il plugin usa invece il selettore account nativo.
Passo 1: Configura Google Cloud
Crea un progetto e la Google Auth Platform
- Apri Google Cloud Console e crea un progetto, oppure scegline uno esistente. Tutti i client ID devono trovarsi nello stesso progetto.
- Apri Piattaforma Google Auth (la schermata precedentemente chiamata “OAuth consent screen”).
- Sotto Branding, imposta il nome dell'app che vedranno gli utenti, un'email di supporto, i tuoi domini e l'URL della privacy policy.
- Sotto Pubblico, scegli Esterno per le app consumer. Mentre l'app è in Test, solo gli account elencati sotto Utenti di test possono accedere.
- Sotto Accesso ai dati, mantieni il valore predefinito
openid,emaileprofilescopes, a meno che non ne servano altri.
Non è necessario pubblicare in produzione o superare la verifica per gli scopes di base. Gli scopes sensibili (Calendar, Drive, Gmail) richiedono la verifica prima del rilascio pubblico.
Crea gli ID client
Vai su Google Auth Platform > Client (o API e servizi > Credenziali) and create:
| Tipo di client | Cosa inserire | Dove va l'ID |
|---|---|---|
| Applicazione web | Origini JavaScript autorizzate per la tua build web (ad esempio https://app.example.com, http://localhost:5173) |
webClientId |
| iOS | Il tuo bundle ID, più App Store ID e Team ID una volta disponibili | iOSClientId |
| Android (debug) | Nome del pacchetto più SHA-1 di debug | Solo console |
| Android (release) | Nome del pacchetto più SHA-1 della chiave di upload | Solo console |
| Android (Play) | Nome del pacchetto più SHA-1 di Play App Signing | Solo console |
Ottieni i valori SHA-1:
# Debug key and any signing config in build.gradle
cd android && ./gradlew signingReport
# From a signed APK you actually install
keytool -printcert -jarfile android/app/build/outputs/apk/release/app-release.apk
Per le build di Play Store, copia lo SHA-1 da Play Console > Test e rilascio > Integrità dell'app > Certificato chiave di firma dell'app. Se hai prima bisogno di un keystore di rilascio, il Generatore di keystore per Android ne crea uno nel browser. La nostra guida all'ID client Google approfondisce le schermate della console.
Passo 2: Installa il plugin
bun add @capgo/capacitor-social-login
bunx cap sync
Disabilita i provider che non usi in modo che i loro SDK non finiscano nel binario:
// capacitor.config.ts
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'Example',
webDir: 'dist',
plugins: {
SocialLogin: {
providers: {
google: true,
apple: true,
facebook: false,
twitter: false,
},
},
},
};
export default config;
Esegui bunx cap sync dopo aver cambiato provider.
Passo 3: configurazione iOS
Aggiungi lo schema URL con l'ID client invertito
Apri il client iOS in Google Cloud e copia l' URL scheme iOS, che assomiglia a com.googleusercontent.apps.1234567890-abcdef. Aggiungilo a ios/App/App/Info.plist prima della chiusura di </dict>:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.1234567890-abcdef</string>
</array>
</dict>
</array>
If you already have a CFBundleURLTypes array per i deep link, aggiungi una nuova <dict> voce invece di creare una seconda chiave.
Lascia che il SDK di Google gestisca l'URL di callback
In ios/App/App/AppDelegate.swift, importa il SDK e instrada l'URL verso di esso prima di Capacitor:
import GoogleSignIn // add at the top of the file
// Replace the generated application(_:open:options:) method
func application(_ app: UIApplication, open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
if GIDSignIn.sharedInstance.handle(url) {
return true
}
return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
}
Mantieni il ApplicationDelegateProxy chiama @capacitor/app continua a ricevere gli altri deep link.
Passo 4: configurazione Android
L'accesso di base con gli scope predefiniti funziona senza modifiche native. Se richiedi scope aggiuntivi o usi la modalità offline, il plugin deve ricevere i risultati dell'attività, quindi MainActivity deve implementare l'interfaccia marker del plugin:
package com.example.app;
import android.content.Intent;
import com.getcapacitor.BridgeActivity;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginHandle;
import ee.forgr.capacitor.social.login.GoogleProvider;
import ee.forgr.capacitor.social.login.ModifiedMainActivityForSocialLoginPlugin;
import ee.forgr.capacitor.social.login.SocialLoginPlugin;
public class MainActivity extends BridgeActivity implements ModifiedMainActivityForSocialLoginPlugin {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode >= GoogleProvider.REQUEST_AUTHORIZE_GOOGLE_MIN
&& requestCode < GoogleProvider.REQUEST_AUTHORIZE_GOOGLE_MAX) {
PluginHandle handle = getBridge().getPlugin("SocialLogin");
if (handle == null) return;
Plugin plugin = handle.getInstance();
if (plugin instanceof SocialLoginPlugin) {
((SocialLoginPlugin) plugin).handleGoogleLoginIntent(requestCode, data);
}
}
}
@Override
public void IHaveModifiedTheMainActivityForTheUseWithSocialLoginPlugin() {}
}
Senza di essa, le chiamate con scopes vengono rifiutate con “You CANNOT use scopes without modifying the main activity”.
Per l'emulatore, usa un'immagine di sistema con l'etichetta Google Play e accedi a un account Google nelle impostazioni del dispositivo. Le immagini senza Play services restituiscono NoCredentialException.
Passo 5: Configurazione web
Aggiungi ogni origine da cui servi la build web a quelle del client Web Origini JavaScript autorizzate, inclusa la porta (http://localhost:5173). Chiama initialize early: il plugin inietta il tag script di Google e il login fallisce se viene eseguito prima che lo script sia pronto.
Passaggio 6: Inizializzazione e login
import { SocialLogin } from '@capgo/capacitor-social-login';
const WEB_CLIENT_ID = '1234567890-web.apps.googleusercontent.com';
const IOS_CLIENT_ID = '1234567890-ios.apps.googleusercontent.com';
export async function initAuth() {
await SocialLogin.initialize({
google: {
webClientId: WEB_CLIENT_ID, // Android + web
iOSClientId: IOS_CLIENT_ID, // iOS
iOSServerClientId: WEB_CLIENT_ID, // same as webClientId, required for offline mode on iOS
mode: 'online',
},
});
}
export async function signInWithGoogle() {
try {
const { result } = await SocialLogin.login({
provider: 'google',
options: {},
});
if (result.responseType !== 'online' || !result.idToken) {
throw new Error('Expected an ID token from Google');
}
const res = await fetch('https://api.example.com/auth/google', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ idToken: result.idToken }),
});
return res.json();
} catch (error: any) {
if (error?.code === 'USER_CANCELLED') return null;
throw error;
}
}
La risposta online contiene:
| Campo | Note |
|---|---|
idToken |
JWT OpenID Connect. Invialo al tuo server |
accessToken |
Per chiamare le API Google dal client. Può essere null su Android quando vengono richiesti solo gli scope predefiniti |
profile |
email, name, givenName, familyName, imageUrl, id |
responseType |
'online' |
Opzioni di visualizzazione solo per Android
Il options l'oggetto accetta style: 'bottom' per l'interfaccia bottom sheet, oltre a filterByAuthorizedAccounts e autoSelectEnabled per gli utenti che tornano. Lascia filterByAuthorizedAccounts disattivato se supporti gli account Family Link. forceRefreshToken: true richiede ad Android un nuovo access token invece di uno in cache.
Richiesta di scope aggiuntivi
const { result } = await SocialLogin.login({
provider: 'google',
options: {
scopes: ['https://www.googleapis.com/auth/calendar.readonly'],
},
});
Ricorda la MainActivity modifica su Android e aggiungi lo scope in Accesso ai dati su Google Cloud.
Modalità online vs offline
| Online (predefinito) | Offline | |
|---|---|---|
| Restituisce | ID token, access token, profilo | serverAuthCode solo |
| Backend necessario | Solo per verificare il token | Sì, per scambiare il code |
| refresh token di Google | Rimane con Google SDK sul dispositivo | Memorizzato sul tuo server |
| Usa quando | Devi solo sapere chi è l'utente | Il tuo server chiama le API Google mentre l'utente è offline |
logout, isLoggedIn, refresh |
Supportato | Non supportato |
La modalità offline su iOS richiede iOSServerClientId, e su Android richiede la MainActivity modifica.
Logout e verifica della sessione
await SocialLogin.isLoggedIn({ provider: 'google' }); // { isLoggedIn: boolean }
await SocialLogin.logout({ provider: 'google' });
Su Android, logout cancella anche lo stato del Credential Manager, in modo che la selezione dell'account riappaia la prossima volta.
Passo 7: Verifica l'ID token sul tuo server
import { OAuth2Client } from 'google-auth-library';
const client = new OAuth2Client();
export async function verifyGoogleToken(idToken: string) {
const ticket = await client.verifyIdToken({
idToken,
audience: [
'1234567890-web.apps.googleusercontent.com',
'1234567890-ios.apps.googleusercontent.com',
],
});
const payload = ticket.getPayload();
if (!payload) throw new Error('Empty token payload');
return {
googleUserId: payload.sub,
email: payload.email,
emailVerified: payload.email_verified === true,
name: payload.name,
};
}
Usa sub come chiave utente stabile. Collega un account esistente tramite email solo se email_verified è true. Accettare entrambi i client ID come audience mantiene validi i token di tutte le piattaforme. Poi emetti la tua sessione. Se usi un backend gestito, segui Supabase con Capacitor Social Login o nel Guida a Firebase Google. Neon Auth gestisce Google tramite un redirect OAuth, che @capgo/capacitor-neon viene eseguito in modo nativo.
Risoluzione problemi
| Errore | Causa | Soluzione |
|---|---|---|
[28444] Developer console is not set up correctly |
Nome del pacchetto, SHA-1 o webClientId discrepanza |
Usa l'ID client Web, registra la SHA-1 della build installata e tieni tutti i client in un unico progetto |
| Funziona in debug, fallisce da Play Store | Play firma di nuovo l'app | Aggiungi un client Android con lo SHA-1 di Play App Signing |
[16] Account reauth failed |
Stato account in cache obsoleto, account non è un utente di test o l'utente ha disabilitato l'app | Il plugin fa un retry automatico. Controlla utenti di test, External audience e SHA-1 di Play signing |
NoCredentialException |
Nessun account Google sul dispositivo o emulatore senza Play services | Usa un'immagine di sistema Google Play e accedi |
USER_CANCELLED subito dopo aver scelto un account |
Di solito è ancora un mismatch di SHA-1 o del client ID | Fix console setup before treating it as a real cancel |
| Crash su iOS: “missing support for the following URL schemes” | Reversed client ID mancante in Info.plist |
Aggiungi la com.googleusercontent.apps... schema |
| Web: “L’origine specificata non è consentita per l’ID client specificato” | Origin mancante sul client Web | Aggiungi l'origin esatto, inclusa la porta |
access_denied con “app has not completed the Google verification process” |
L'account non è un utente di test durante la fase di Testing | Aggiungilo sotto Audience > Test users |
| Schermata di login Google interrotta su iOS | @capacitor/privacy-screen copre la vista SDK |
Chiama PrivacyScreen.disable() prima login |
Su Android, filtra Logcat per GoogleProvider. Il plugin logga il nome del package, la firma SHA-1 e un webClientId, che puoi confrontare con la console in un minuto.
Rilascio e manutenzione
Le modifiche alla console possono richiedere alcune ore per propagarsi, quindi non ruotare gli ID client il giorno del rilascio. Una volta che la configurazione nativa è in un build per lo store, le modifiche lato client come scope, gestione degli errori o l'URL del backend possono essere pubblicate tramite Live updates di Capgo. Se il tuo team non ha un Mac per i rilasci iOS, Build Capgo compila e firma il binario iOS nel cloud.
Guide correlate
- Come effettuare il login con Apple usando Capacitor, che ti servirà su iOS se Google è il tuo metodo di login principale.
- Come aggiungere l'autenticazione a un'app Capacitor per scegliere tra social login, OIDC, passkey e Better Auth.
- Pagina del plugin Social Login e il Documentazione setup Google su Android.