Files
supabase/examples/auth/expo-social-auth/components/social-auth-buttons/google/google-sign-in-button.web.tsx
MDL 3139f85b5d docs(react-native): Expo cross-platform social sign-in with complete example (#38178)
* docs(react-native): create the basic expo project

* docs(react-native): cross-platform Apple social sign-in

* docs(react-native): cross-platform Google social sign-in

* docs(react-native): fix typos

* docs(react-native): remove wrong entry in the `Connection` component

* Correct typos

* Prettier

* Draft

* Draft

* docs(react-native): use kebab-case file naming convention in Expo guide

- use kebab-case file naming convention in Expo guide
- add trailing semicolon to align with the standard Expo template conventions

* docs(react-native): use kebab-case file naming convention in Expo social auth example

* docs(react-native): update the packages of the Expo social auth example

* Fix

* Draft

* Changes

* Correct log message

---------

Co-authored-by: Chris Chinchilla <chris.ward@supabase.io>
Co-authored-by: Chris Chinchilla <chris@chrischinchilla.com>
2025-09-19 16:53:35 +02:00

73 lines
2.2 KiB
TypeScript

import { supabase } from '@/lib/supabase';
import { CredentialResponse, GoogleLogin, GoogleOAuthProvider } from '@react-oauth/google';
import { SignInWithIdTokenCredentials } from '@supabase/supabase-js';
import { useEffect, useState } from 'react';
import 'react-native-get-random-values';
export default function GoogleSignInButton() {
// Generate secure, random values for state and nonce
const [nonce, setNonce] = useState('');
const [sha256Nonce, setSha256Nonce] = useState('');
async function onGoogleButtonSuccess(authRequestResponse: CredentialResponse) {
console.debug('Google sign in successful:', { authRequestResponse })
if (authRequestResponse.clientId && authRequestResponse.credential) {
const signInWithIdTokenCredentials: SignInWithIdTokenCredentials = {
provider: 'google',
token: authRequestResponse.credential,
nonce: nonce,
}
const { data, error } = await supabase.auth.signInWithIdToken(signInWithIdTokenCredentials)
if (error) {
console.error('Error signing in with Google:', error)
}
if (data) {
console.log('Google sign in successful:', data)
}
}
}
function onGoogleButtonFailure() {
console.error('Error signing in with Google')
}
useEffect(() => {
function generateNonce(): string {
const array = new Uint32Array(1);
window.crypto.getRandomValues(array);
return array[0].toString();
};
async function generateSha256Nonce(nonce: string): Promise<string> {
const buffer = await window.crypto.subtle.digest('sha-256', new TextEncoder().encode(nonce));
const array = Array.from(new Uint8Array(buffer));
return array.map(b => b.toString(16).padStart(2, '0')).join('');
}
let nonce = generateNonce();
setNonce(nonce);
generateSha256Nonce(nonce)
.then((sha256Nonce) => { setSha256Nonce(sha256Nonce) });
}, []);
return (
<GoogleOAuthProvider
clientId={process.env.EXPO_PUBLIC_GOOGLE_AUTH_WEB_CLIENT_ID ?? ''}
nonce={sha256Nonce}
>
<GoogleLogin
nonce={sha256Nonce}
onSuccess={onGoogleButtonSuccess}
onError={onGoogleButtonFailure}
useOneTap={true}
auto_select={true}
/>
</GoogleOAuthProvider>
);
}