Salta al contenuto principale

Come accedere con Google usando Capacitor (2026)

Configura Google Sign-In in un'app Capacitor 8: client ID, SHA-1, URL scheme iOS, Android Credential Manager, verifica dell'ID token e fix per l'errore 28444.

Selettore account Google Sign-In all'interno di un'app Capacitor utilizzando il plugin Capgo Social Login

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

  1. Apri Google Cloud Console e crea un progetto, oppure scegline uno esistente. Tutti i client ID devono trovarsi nello stesso progetto.
  2. Apri Piattaforma Google Auth (la schermata precedentemente chiamata “OAuth consent screen”).
  3. Sotto Branding, imposta il nome dell'app che vedranno gli utenti, un'email di supporto, i tuoi domini e l'URL della privacy policy.
  4. Sotto Pubblico, scegli Esterno per le app consumer. Mentre l'app è in Test, solo gli account elencati sotto Utenti di test possono accedere.
  5. Sotto Accesso ai dati, mantieni il valore predefinito openid, email e profile scopes, 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 &gt; 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.

Live updates per le app Capacitor

Quando un bug nel web-layer è live, rilascia la fix tramite Capgo invece di aspettare giorni l'approvazione degli store. Gli utenti ricevono l'update in background, mentre le modifiche native restano nel normale processo di review.

Ultimi articoli dal blog

Capgo ti offre gli insight migliori che ti servono per creare un'app mobile davvero professionale.