Google Login With Supabase In React Native: A Quick Guide

by Faj Lennon 58 views

Hey guys! Ever wanted to add that slick Google login to your React Native app using Supabase for backend? Well, you're in the right spot! This guide will walk you through setting it all up, step by step. We're diving deep into the code and configurations to make sure you've got a smooth experience. Let's get started!

Setting Up Your Supabase Project

First things first, you need a Supabase project. If you haven't already, head over to Supabase and create a new project. This is where all your data will live, and Supabase will handle the backend magic for us. Once your project is created, grab your Supabase URL and anon key – you'll need these later to connect your React Native app.

Next, you have to configure the authentication settings to allow Google as an OAuth provider. To do this, navigate to the Authentication section in your Supabase project dashboard, then go to Providers. Find Google in the list and enable it. Supabase will prompt you for a Client ID and a Client Secret. To get these, you will need to set up a Google Cloud Project.

To set up your Google Cloud Project, go to the Google Cloud Console. Create a new project and then navigate to the APIs & Services > Credentials section. Here, you will create an OAuth 2.0 Client ID. You'll need to configure the consent screen by providing an app name, your email address, and other required information. Once you've done this, you can create the credentials.

When creating the OAuth 2.0 Client ID, select "Web application" as the application type. Give it a name (e.g., "Supabase React Native App"). Under Authorized JavaScript origins, put your Supabase URL. Under Authorized redirect URIs, you should input your Supabase URL followed by /auth/v1/callback. For example: https://your-project-id.supabase.co/auth/v1/callback. This is crucial because Google will redirect users back to this URL after they authenticate.

Once you've created the OAuth 2.0 Client ID, Google will provide you with a Client ID and a Client Secret. Copy these values and paste them into the corresponding fields in your Supabase Google provider settings. Save the settings in Supabase, and you're all set on the backend!

Remember, keeping your Client Secret safe is super important. Treat it like a password and don't expose it in your client-side code. Supabase handles the sensitive bits securely on the server side, so you don’t have to worry about that.

Setting Up Your React Native Project

Now, let's move over to the React Native side of things. If you don't already have a React Native project, create one using Expo or React Native CLI. For this guide, we'll assume you're using Expo because it simplifies a lot of things, especially when dealing with authentication.

expo init your-app-name
cd your-app-name

Next, you'll need to install the Supabase client library for JavaScript. This library provides all the methods you need to interact with your Supabase backend, including authentication, database operations, and more. Run the following command to install it:

npm install @supabase/supabase-js @react-native-async-storage/async-storage
# or
yarn add @supabase/supabase-js @react-native-async-storage/async-storage

We also install @react-native-async-storage/async-storage which is needed to persist the user session.

Configuring Supabase Client in React Native

Now that you have the Supabase library installed, you need to configure it in your React Native app. Create a new file, supabase.js, in your project directory. This file will contain the Supabase client instance that you'll use throughout your app. Add the following code to supabase.js:

import { createClient } from '@supabase/supabase-js';
import AsyncStorage from '@react-native-async-storage/async-storage';

const supabaseUrl = 'YOUR_SUPABASE_URL';
const supabaseAnonKey = 'YOUR_SUPABASE_ANON_KEY';

export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
  localStorage: AsyncStorage as any,
  autoRefreshToken: true,
  persistSession: true,
  detectSessionInUrl: false,
});

Replace YOUR_SUPABASE_URL and YOUR_SUPABASE_ANON_KEY with your actual Supabase URL and anon key from your Supabase project dashboard. Make sure to keep these values secure and don't commit them to your repository. Use environment variables instead.

Implementing Google Login

Alright, let's get to the fun part: implementing Google login in your React Native app. You'll need to create a button that, when pressed, initiates the Google login flow. For this, we'll use Supabase's signInWithOAuth method.

First, let's create a simple component for our login screen. In your App.js or any other component file, add the following code:

import React, { useState, useEffect } from 'react';
import { Button, View, Text, StyleSheet } from 'react-native';
import { supabase } from './supabase';

export default function App() {
  const [session, setSession] = useState(null);

  useEffect(() => {
    supabase.auth.getSession().then(({ data: { session } }) => {
      setSession(session)
    })

    supabase.auth.onAuthStateChange((_event, session) => {
      setSession(session)
    })
  }, [])

  async function signInWithGoogle() {
    const { error } = await supabase.auth.signInWithOAuth({
      provider: 'google',
    });

    if (error) {
      console.error('Error signing in with Google:', error);
    }
  }

  return (
    <View style={styles.container}>
      {session ? (
        <Text>You are signed in!</Text>
      ) : (
        <Button title="Sign in with Google" onPress={signInWithGoogle} />
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

In this code, we import the supabase client we configured earlier. We also create a signInWithGoogle function that calls supabase.auth.signInWithOAuth with the google provider. When the button is pressed, this function will redirect the user to the Google login page.

After the user authenticates with Google, they will be redirected back to your app. Supabase handles the exchange of the authorization code for a user session. The session is then stored securely. The useEffect hook is used to detect the session automatically and update the UI accordingly.

Handling the Redirect URL

React Native apps, especially when using Expo, require a specific setup to handle redirect URLs correctly. Expo uses a custom scheme to redirect users back to the app after authentication.

Make sure you have configured the redirect URL in your Supabase project and Google Cloud Console as mentioned earlier. For Expo, the redirect URL should look something like YOUR_EXPO_SCHEME://auth.supabase.co/auth/v1/callback. Replace YOUR_EXPO_SCHEME with the scheme defined in your app.json or app.config.js file.

To find your Expo scheme, check your app.json or app.config.js file. Look for the scheme property. If you don't have one, you can add it like this:

{
  "expo": {
    "name": "YourAppName",
    "slug": "your-app-name",
    "scheme": "your-app-scheme",
    // other configurations
  }
}

Displaying User Information

Once the user is signed in, you'll likely want to display their information, such as their name and email address. You can access this information from the session object. Modify your App.js component to display the user's email address:

import React, { useState, useEffect } from 'react';
import { Button, View, Text, StyleSheet } from 'react-native';
import { supabase } from './supabase';

export default function App() {
  const [session, setSession] = useState(null);

  useEffect(() => {
    supabase.auth.getSession().then(({ data: { session } }) => {
      setSession(session)
    })

    supabase.auth.onAuthStateChange((_event, session) => {
      setSession(session)
    })
  }, [])

  async function signInWithGoogle() {
    const { error } = await supabase.auth.signInWithOAuth({
      provider: 'google',
    });

    if (error) {
      console.error('Error signing in with Google:', error);
    }
  }

  async function signOut() {
    await supabase.auth.signOut()
  }

  return (
    <View style={styles.container}>
      {session ? (
        <View>
          <Text>Signed in: {session.user.email}</Text>
          <Button title="Sign Out" onPress={signOut} />
        </View>
      ) : (
        <Button title="Sign in with Google" onPress={signInWithGoogle} />
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Handling Sign Out

Adding a sign-out feature is just as important. Use the signOut method from Supabase auth to clear the user's session. Here’s how you can implement a sign-out button:

async function signOut() {
  const { error } = await supabase.auth.signOut();
  if (error) {
    console.error('Error signing out:', error);
  }
}

Best Practices and Troubleshooting

  • Secure Your Credentials: Never hardcode your Supabase URL and anon key directly in your code. Use environment variables instead.
  • Handle Errors: Always handle errors gracefully. Display user-friendly error messages instead of crashing the app.
  • Check Redirect URLs: Ensure your redirect URLs are correctly configured in both Supabase and Google Cloud Console.
  • Use Deep Linking: For production apps, consider using deep linking to handle redirects more reliably.
  • Review Supabase Documentation: Supabase’s official documentation is a great resource for troubleshooting and advanced configurations.

Conclusion

And that's a wrap, folks! You've successfully integrated Google login into your React Native app using Supabase. This setup not only simplifies user authentication but also provides a secure and scalable backend solution. Remember to follow best practices for security and error handling to ensure a smooth user experience. Happy coding, and feel free to explore more of what Supabase has to offer!