Supabase OAuth: configurando Google SignIn em Flutter.

Dio Silva
Flutter Brasil
Published in
11 min readApr 16, 2024

O Supabase é uma plataforma open-source que oferece uma variedade de serviços backend, incluindo autenticação, armazenamento e banco de dados em tempo real. Uma das funcionalidades mais úteis do Supabase é a autenticação OAuth com diversos provedores, incluindo o Google. Neste artigo, vamos explorar como configurar o Google SignIn com o Supabase em um aplicativo Flutter.

Pré-requisitos

Antes de começarmos, você precisa ter o Flutter instalado em seu ambiente de desenvolvimento, um projeto em Flutter e um projeto ativo no Supabase. Além disso, é necessário ter uma conta no Google Cloud Console para criar as credenciais OAuth.

Passos para Configuração

1. Configuração no Supabase

1.1. Seleção ou criação de um projeto no Supabase

Caso você tenha um projeto existente no Supabase e deseje usa-lo, acesse o Supabase Dashboard e considere pular a sessão 1.2.

1.2. Crie um projeto no Supabase

Acesse o Supabase Dashboard e crie um novo projeto clicando em “new project”.
Obs.: Caso não tenha uma organização no Supabase para vincular ao seu projeto será necessário criar uma.

Selecione a organização desejada e dê um nome ao seu projeto. Insira uma senha para o seu banco de dados, selecione a região do servidor e depois clique em “Create new project”. Como dito no primeiro tópico desta sessão, caso não possua uma organização crie uma para vincular ao seu projeto.

Após criado seu projeto será configurado e isso levará alguns minutos, ao término das configurações será possível acessa-lo no Supabase Dashboard.

2. Obtendo certificado da sua aplicação

2.1 Acesse seu projeto Flutter

Como dito inicialmente presume-se que você tenha um projeto Flutter ativo para que possa aplicar este conhecimento, caso contrario você pode criar seu projeto neste momento para que possamos dar continuidade.

2.2 Gerando certificado fingerprint

Existem varias formas de obter o mesmo resultado, deixarei aqui alguns métodos para que consiga gerar seu certificado SHA1.

1 — Terminal

Navegue até a pasta do projeto que você criou — ou existente no terminal — e rode o comando abaixo.

keytool -list -v -alias androiddebugkey -keystore C:\Users\YOURUSERNAME\.android\debug.keystore

Notas:

Lembre-se de trocar “YOURUSERNAME” no path do keystore pelo nome do usuário do seu computador.

Senha padrão do comando: android

O Resultado será algo semelhante a imagem baixo, contendo a chave SHA1.

2— Sign Report

Navegue até a pasta android dentro do seu projeto Flutter.

exemplo:
C:\Users\Dio\Documents\Meus Projetos\meu_projeto_flutter> cd android

C:\Users\Dio\Documents\Meus Projetos\meu_projeto_flutter\android>

Dentro da pasta android rode o seguinte comando no terminal: ./gradlew signingReport

C:\Users\Dio\Documents\Meus Projetos\meu_projeto_flutter\android> ./gradlew signingReport

O Resultado será algo semelhante a imagem baixo, contendo a chave SHA1 e outras chaves também.

2.3 Chave SHA1

Em ambos métodos utilizados obtemos resultados semelhantes, contendo a chave SHA1 (Guarde-a, pois ela será utilizada em um futuro próximo).

3. Configuração no Console do Google Cloud

3.1. Acesso ao Google Cloud Console

Acesse o Google Cloud Console.

3.2. Criação de um Novo Projeto

Crie um novo projeto clicando no menu suspenso no topo da página.

ao lado do nome do projeto atual e selecione “Novo Projeto”. Dê um nome ao seu projeto e clique em “Criar”.

Clique em “Novo Projeto”.

Dê um nome ao seu projeto e clique em “Criar”.

Feito isso, precisamos criar as credenciais do Google Auth.

3.3. Criação de Credenciais

No menu lateral, selecione o projeto que você acabou de criar.

Com o projeto selecionado, na barra de pesquisa, procure por: “Tela de permissões OAuth” e clique em “Tela de permissão OAuth”.

Na Tela de permissões OAuth selecione “Externo” e depois clique em “Criar”.

Agora dê um nome para o seu app, selecione um e-mail para suporte e insira um para contato com o desenvolvedor. Feito isso clique em “Salvar e Continuar”.

Agora na aba de “Escopos”, apenas clique em “Salvar e Continuar”.

Logo após, na aba “Usuários de teste”, apenas clique em “Salvar e Continuar”.

Ao fim estaremos na aba de “Resumo”, como demonstra a imagem abaixo, apenas clique em “Voltar para o Painel”.

Ao finalizar os passos anteriores estamos aptos para criar as credenciais. Acesse o menu “Credenciais” que fica no lado esquerdo da tela.

3.4. Configuração do ID do Cliente OAuth e Relacionando com Supabase

Na aba Credenciais, clique em “Criar credenciais” e depois em “ID do Cliente OAuth”, como mostra a imagem abaixo.

Para configurar o ID do cliente OAuth, no “Tipo de Aplicativo” selecione “Aplicativo da Web” e insira um nome para seu cliente.

Em URIs de redirecionamento autorizados precisamos do Callback URL (for OAuth), que está disponível no seu projeto Supabase. Volte ao Supabase, selecione seu projeto, acesse o menu lateral e clique em “Authentication”.

Em Authentication, no menu de “Configuration” clique em “Providers”.

Você irá se deparar com vários provedores de autenticação que o Supabase disponibiliza integração, como neste artigo estamos abordando autenticação com o Google, selecionaremos “Google”.

Após selecionar o Google, habilite o “Sign in with Google” e copie o CallBack URL (for OAuth) para inserir no URIs de redirecionamento autorizados do Cliente ID do Google.

Feito isso, volte a criação do ID do cliente OAuth no Google e insira a CallBack URL (for OAuth) copiada do provedor google e fornecida pelo Supabase, depois clique em “Criar”.

Com nossas credenciais em mãos, podemos relacionar o ID do nosso cliente e a chave secreta. No menu credenciais é possível acessar os IDs que você acabou de criar.

Clique no ID do cliente OAuth 2.0 que deseja acessar as credenciais e copie o ID.

Com ID do cliente em mãos volte ao Supabase e na aba do google insira o ID no “Client ID (for OAuth)”.

Volte no ID do cliente OAuth 2.0 e copie a chave secreta do cliente.

Depois disso volte ao Supabase e cole a senha no “Client Secret(for OAuth)” e habilite o “Skip nonce Checks”.

Você deve ter percebido que faltou completar um campo no Supabase sendo ele: “Authorized Client IDs (for Android, One Tap, and Chrome Extensions)”. Bem, iremos resolver isso agora, voltaremos as Credenciais do Google e criaremos uma nova credencial.

Dessa vez no “Tipo de aplicativo” selecione “Android”, em seguida nomeie para seu Client ID.

Agora precisamos informar o nome do pacote, essa informação pode ser obtida no seu projeto Flutter dentro da pasta: android\app\build.gradle

Copiaremos o applicationId, esse é nome do seu pacote. Após copiar volte a página de criação da nova credencial e no campo “Nome do pacote” cole o nome do pacote do seu app. No meu caso: “com.example.flutter_supabase_googleauth”

Você deve ter percebido que passamos um tempinho sem citar onde seria utilizado a chave SHA1, e a reposta é: agora! Espero que tenha guardado sua chave, com ela em mãos siga para o campo “Impressão digital para certificação SHA-1”, cole sua chave e clique em página “Criar”.

É possível observar que agora você possui dois Clients IDs, um para web-application e outro para android. Identifique o Client ID Android e copie seu id.

Utilizaremos este ID para completar o campo que estava faltando no Supabase, que é o campo “Authorized Client IDs (for Android, One Tap, and Chrome extensions)”, cole o Android client ID no campo e por fim clique em “Salvar”.

4. Implementação no Flutter

4.1. Adicionando dependências

Precisamos de duas dependências para dar continuidade a implementação no seu projeto Flutter. Elas podem ser encontradas no pub.dev, são elas:

1 — google_sign_in
2 — supabase_flutter

Com as dependências em mãos adicione-as ao pubspec.yaml do seu projeto.

4.2. Configurando o Supabase

Neste exemplo usei um projeto criado somente para este propósito, mas nada impede de seguir estes passos em um projeto já existente.

No método main.dart do projeto iremos inserir algumas linhas código para iniciar a comunicação com o Supabase. Estas informações também podem ser obtidas no site oficial do Supabase ou clicando aqui.

import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

import 'login_screen.dart';

void main() async {
/// TODO: Atualize com suas credenciais do Supabase
await Supabase.initialize(
url: 'https://btuegolagkhfbazgtmpo.supabase.co',
anonKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJ0dWVnb2xhZ2toZmJhemd0bXBvIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTMyODU2MDksImV4cCI6MjAyODg2MTYwOX0.pOEpUKNGGLulpElcE12g7YkrFUdXFfkO0IywOrHG_w8',
);
runApp(const MyApp());
}

final supabase = Supabase.instance.client;

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Auth',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const LoginScreen(),
);
}
}

Podemos observar que é necessário informar a “URL” do projeto Supabase e também a “anonKey”. — Observar o exemplo de código acima.

Para obtermos tal informação devemos seguir para as configurações do projeto “Project Configuration”, no menu lateral do Supabase, depois selecionar API. Pronto! Você já tem acesso as suas credenciais e já pode inicializar seu Supabase.

Com seu main.dart configurado agora precisamos de um método, uma tela de login e de um perfil para que possamos testar nossas configurações. Logo abaixo você encontra alguns exemplos que o próprio Supabase sugere para o teste.

método: _googleSignIn()

Future<AuthResponse> _googleSignIn() async {
/// TODO: update the Web client ID with your own.
///
/// Web Client ID que voce criou no Google Cloud.
const webClientId = '1047343795704-uaq2eu4a6vuvg93c66sib8ctqi6ehj9l.apps.googleusercontent.com';

/// TODO: update the iOS client ID with your own.
///
/// iOS Client ID that you registered with Google Cloud.
//const iosClientId = 'my-ios.apps.googleusercontent.com';

// Google sign in on Android will work without providing the Android
// Client ID registered on Google Cloud.

final GoogleSignIn googleSignIn = GoogleSignIn(
serverClientId: webClientId,
);
final googleUser = await googleSignIn.signIn();
final googleAuth = await googleUser!.authentication;
final accessToken = googleAuth.accessToken;
final idToken = googleAuth.idToken;

if (accessToken == null) {
throw 'No Access Token found.';
}
if (idToken == null) {
throw 'No ID Token found.';
}

return supabase.auth.signInWithIdToken(
provider: OAuthProvider.google,
idToken: idToken,
accessToken: accessToken,
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Login'),
),
body: Center(
child: ElevatedButton(
onPressed: _googleSignIn,
child: const Text('Google login'),
),
),
);
}
}

Login Screen:

import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

import 'main.dart';
import 'profile_screen.dart';

class LoginScreen extends StatefulWidget {
const LoginScreen({super.key});

@override
State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
@override
void initState() {
_setupAuthListener();
super.initState();
}

void _setupAuthListener() {
supabase.auth.onAuthStateChange.listen((data) {
final event = data.event;
if (event == AuthChangeEvent.signedIn) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const ProfileScreen(),
),
);
}
});
}

//Este metodo eh responsavel pela autenticacao com o google
//e envio para o supabase
Future<AuthResponse> _googleSignIn() async {
/// TODO: update the Web client ID with your own.
///
/// Web Client ID que voce criou no Google Cloud.
const webClientId = '1047343795704-uaq2eu4a6vuvg93c66sib8ctqi6ehj9l.apps.googleusercontent.com';

/// TODO: update the iOS client ID with your own.
///
/// iOS Client ID that you registered with Google Cloud.
//const iosClientId = 'my-ios.apps.googleusercontent.com';

// Google sign in on Android will work without providing the Android
// Client ID registered on Google Cloud.

final GoogleSignIn googleSignIn = GoogleSignIn(
serverClientId: webClientId,
);
final googleUser = await googleSignIn.signIn();
final googleAuth = await googleUser!.authentication;
final accessToken = googleAuth.accessToken;
final idToken = googleAuth.idToken;

if (accessToken == null) {
throw 'No Access Token found.';
}
if (idToken == null) {
throw 'No ID Token found.';
}

return supabase.auth.signInWithIdToken(
provider: OAuthProvider.google,
idToken: idToken,
accessToken: accessToken,
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Login'),
),
body: Center(
child: ElevatedButton(
onPressed: _googleSignIn,
child: const Text('Google login'),
),
),
);
}
}

Profile Screen:

import 'package:flutter/material.dart';

import 'login_screen.dart';
import 'main.dart';

class ProfileScreen extends StatelessWidget {
const ProfileScreen({super.key});

@override
Widget build(BuildContext context) {
final user = supabase.auth.currentUser;
final profileImageUrl = user?.userMetadata?['avatar_url'];
final fullName = user?.userMetadata?['full_name'];
return Scaffold(
appBar: AppBar(
title: const Text('Profile'),
actions: [
TextButton(
onPressed: () async {
await supabase.auth.signOut();
if (context.mounted) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => const LoginScreen()),
);
}
},
child: const Text('Sign out'),
)
],
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (profileImageUrl != null)
ClipOval(
child: Image.network(
profileImageUrl,
width: 100,
height: 100,
fit: BoxFit.cover,
),
),
const SizedBox(height: 16),
Text(
fullName ?? '',
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 32),
],
),
),
);
}
}

4.3. Hora do teste!

Tudo configurado agora podemos buildar nosso projeto para o teste! Escolha seu AVD(emulador) e rode o projeto. Com tudo funcionando seu projeto executará e apresentará a tela de login, clicando no botão “Google login” é possível selecionar uma conta cadastrada no smartphone e logo em seguida — quando logado — será mostrado o avatar e o nome de usuário da conta.

5. Repositório do projeto

Encontre o código fonte deste projeto no github do Flutter Brasil, clique aqui para acessa-lo.

6. Agradecimentos

Agradeço muito por ter lido o nosso artigo sobre Flutter! É ótimo saber que você está interessado no desenvolvimento com Flutter e espero que o artigo tenha sido útil para você.

Gostaria de convidá-lo a se juntar à nossa comunidade Flutter Brasil. Temos uma comunidade vibrante e acolhedora de desenvolvedores que estão sempre dispostos a ajudar e compartilhar conhecimento.

Você pode se juntar a nós, no nosso grupo do Discord ou no Linkedin, para ficar por dentro das últimas novidades e discussões sobre Flutter.

Siga também minhas redes: Github, Linkedin.

Espero vê-lo em nossa comunidade em breve!

--

--