Google authentication with Expo & Supabase

Search for a command to run...

Thank you, however it's not redirecting me to the app. Just redirects me to my website in the browser
Update, you need to make sure the schema url i.e. mysupabaseapp is the same one you set in app.json in expo.scheme
You are welcome! I'm glad to hear it was useful :)
This article was a shining gem in a lake of information. I didn't have a proper guide to help me integrate expo with supabase and get a google login, but this article made it easy. Thank you so much. However, when I logged in with google, I get the following warning statement, did you ever have this problem?
// Warning Provided value to SecureStore is larger than 2048 bytes. An attempt to store such a value will throw an error in SDK 35.
I used below code.
// Code SecureStore.setItemAsync( "google-access-token", JSON.stringify(data.provider_token) );
Actually, I don't think this code is affecting anything, but in the supabase function I create with createClient, I'm assigning an ExpoSecureStorageAdapter to auth.storage, and I'm wondering if I'm settingItem to all the data that is automatically handed over by google.
Hey! Thanks for the comment! I'm glad to hear that the article was helpful :)
I saw the warning you mentioned, but I got that warning while trying to store the entire "data" object. Based on what I've read, I think the ExpoSecureStorageAdapter will save the access token, refresh token, and other info, but I'm not sure if the provider token is being stored for security reasons.
Will take a look at this later and come back with a reply if I find new info. Thanks for the heads-up!
In this series, I'll guide you through the entire process of building a mobile app with Expo, Supabase, and SpiroKit. We'll cover project setup, auth flow, social login and publishing to the stores.
Expo is an invaluable tool when it comes to developing mobile apps, offering a rich SDK with a wide range of packages. With services like EAS Build, the process of publishing your app becomes effortless. However, if your goal is to create a SaaS (Sof...
💡 This is the third part of the "Collecting payments" series. Before proceeding, make sure to read Part 1, Part 2 & Part 3 We've finally reached the last part of the series! With all the tedious aspects taken care of, we just need to connect everyt...

💡 This is the third part of the "Collecting payments" series. Before proceeding, make sure to read Part 1 and Part 2 Before diving into this third part, I highly recommend watching this video to become familiar with some essential RevenueCat conce...

💡 This is the third part of the "Collecting payments" series. Before proceeding, make sure to read Part 1 SpiroKit for SaaS In case you want to save weeks of painful hours of work & research on your next React Native app, checkout SpiroKit for Sa...

Introduction Creating a mobile app involves numerous challenges and time-consuming tasks that must be completed before we can release our app in the stores. In-app purchases and subscriptions are especially difficult examples of this. They require co...

Building apps take time Building a mobile app is a challenging task. From coming up with an idea, prototyping, and finally building the app, there are many things to consider and problems we'll have to figure out: How do we make sure the entire app ...

While building a mobile app for a SaaS, chances are you’re going to deal with social login sooner or later, and sometimes, this can be a little bit overwhelming.
However, the benefits of providing these additional mechanisms can drastically improve your users’ experience with the app. You can also request permission to access certain information about your users that could allow you to further tailor the experience based on personal preferences.
Popular social providers such as Google, Facebook, Twitter, and more, follow a common open standard known as OAuth, so the steps required to integrate each provider are similar.
Thankfully, if you are using Supabase as your database, you can easily add social login to your app,
In this article, we’ll focus on adding Google as our first social provider.
I highly recommend reading the previous article in the series first, which provides essential instructions for setting up your Supabase and Expo projects. Once you've gone through that article, you'll be fully prepared to dive into the upcoming content.
Here’s a link to the previous post
Before we can utilize Google as a social provider in your Expo app, it is essential to create a project in Google Cloud Platform. To set up your project, follow these steps:
Click on the dropdown at the top left corner.

Click on "New Project" at the top right corner.

Fill in the form and click on "Create", and wait until the project is created. It could take a few seconds or even minutes.
Warning: Once you confirm this form, you won’t be able to change your project id.
Once the project creation is finished, you receive a notification like in the image below. Click “Select project” to set your new project as active, and you’ll be redirected to your new project’s dashboard.


Once you are in your project’s dashboard, use the search box at the top to search for “OAuth consent screen”, and select the first result under “Products and Pages”

In the User Type section, select “External” and hit “Create” to confirm

You’ll be redirected to the “Edit app registration” form. Make sure to review all the information and assets provided here, given that this information will be presented to your users during the login flow.
While following the process, make sure to define your scopes based on your specific needs. Here you can see the full list of available scopes. Besides, add a few testing users so you can complete the auth flow in your app before publishing the Consent Screen.
You can always come back and update your consent screen later. Also, make sure to publish the consent screen once your app is about to be submitted to the stores

In the next step, we’ll need to create an OAuth client ID in Google Cloud. But first, we’ll need to get our callback URL from Supabase.
In the sidebar, click on the “Authentication” button

Under the “Configuration” section, click on “Providers” and click on “Google” to expand the accordion.
Click on the hamburger menu at the top left corner, and navigate to “APIs & Services” → “Credentials”

Click the “+ Create credentials” button, and then select “OAuth client ID”

Under “Application Type”, choose “Web application”. Fill in the name of your app, and click on “Add URI” under the “Authorized redirect URIs” section. Paste your Supabase redirect URL here.

If everything goes right, you’ll get a “Client ID” and “Client Secret”. Make sure to store this information. You’ll need it in the next step.
Go back to your Supabase project, and click the “Authentication” button in the sidebar

Select “Providers” → “Google”
In the previous post, we created a SupabaseContext.tsx and a SupabaseProvider.tsx file.
Let’s update the context by adding the getGoogleOAuthUrl and setOAuthSession methods:
// context/SupabaseContext.tsx
type SupabaseContextProps = {
...
+ getGoogleOAuthUrl: () => Promise<string | null>;
+ setOAuthSession: (tokens: {
+ access_token: string;
+ refresh_token: string;
+ }) => Promise<void>;
};
export const SupabaseContext = createContext<SupabaseContextProps>({
...
+ getGoogleOAuthUrl: async () => "",
+ setOAuthSession: async () => {},
});
Now, we need to also update the provider to implement this new method.
A few things to mention here:
mysupabaseapp://auth as a redirect uri while calling the getGoogleOAuthUrl method. You need to replace mysupabaseapp with your custom scheme. In the next step, I’ll show you how to setup the same redirect URL in your Supabase project so everything works as expected.signInWithOAuth method will return an object that contains the Supabase URL that we need to start the auth flow in the browser later.The setOAuthSession method will allow us to persist the user session using Supabase Auth. In that way, the user won’t need to sign in again the next time.
A few things to mention here:
mysupabaseapp://auth as a redirect uri while calling the getGoogleOAuthUrl method. You need to replace mysupabaseapp with your custom scheme. In the next step, I’ll show you how to setup the same redirect URL in your Supabase project so everything works as expected.signInWithOAuth method will return an object that contains the Supabase URL that we need to start the auth flow in the browser later.setOAuthSession method will allow us to persist the user session using Supabase Auth. In that way, the user won’t need to sign in again the next time.// context/SupabaseProvider.tsx
export const SupabaseProvider = (props: SupabaseProviderProps) => {
const supabase = createClient(
...
);
...
+ const getGoogleOAuthUrl = async (): Promise<string | null> => {
+ const result = await supabase.auth.signInWithOAuth({
+ provider: "google",
+ options: {
+ redirectTo: "mysupabaseapp://google-auth",
+ },
+ });
+
+ return result.data.url;
+ };
+ const setOAuthSession = async (tokens: {
+ access_token: string;
+ refresh_token: string;
+ }) => {
+ const { data, error } = await supabase.auth.setSession({
+ access_token: tokens.access_token,
+ refresh_token: tokens.refresh_token,
+ });
+
+ if (error) throw error;
+
+ setLoggedIn(data.session !== null);
+ };
...
return (
<SupabaseContext.Provider
value={{
...
+ getGoogleOAuthUrl,
+ setOAuthSession
}}
>
...
</SupabaseContext.Provider>
);
};
Install the expo-web-browser package by running the following command
npx expo install expo-web-browser
Finally, we need to update our LoginScreen.tsx
expo-web-browser to load an in-app browser for the login flow.WebBrowser.warmUpAsync() to load the browser in the background before the user taps the button to improve the user experience. You can learn more about this in this linkopenAuthSessionAsync is called with the Supabase URLsetOAuthSession to persist the Supabase session.+ import * as WebBrowser from "expo-web-browser";
+ import * as SecureStore from "expo-secure-store";
const LoginScreen = () => {
const {
login,
+ getGoogleOAuthUrl,
+ setOAuthSession
} = useSupabase();
...
+ React.useEffect(() => {
+ WebBrowser.warmUpAsync();
+
+ return () => {
+ WebBrowser.coolDownAsync();
+ };
+ }, []);
...
+ const onSignInWithGoogle = async () => {
+ setLoading(true);
+ try {
+ const url = await getGoogleOAuthUrl();
+ if (!url) return;
+
+ const result = await WebBrowser.openAuthSessionAsync(
+ url,
+ "mysupabaseapp://google-auth?",
+ {
+ showInRecents: true,
+ }
+ );
+
+ if (result.type === "success") {
+ const data = extractParamsFromUrl(result.url);
+
+ if (!data.access_token || !data.refresh_token) return;
+
+ setOAuthSession({
+ access_token: data.access_token,
+ refresh_token: data.refresh_token,
+ });
+
+ // You can optionally store Google's access token if you need it later
+ SecureStore.setItemAsync(
+ "google-access-token",
+ JSON.stringify(data.provider_token)
+ );
+ }
+ } catch (error) {
+ // Handle error here
+ console.log(error);
+ } finally {
+ setLoading(false);
+ }
+ };
+ const extractParamsFromUrl = (url: string) => {
+ const params = new URLSearchParams(url.split("#")[1]);
+ const data = {
+ access_token: params.get("access_token"),
+ expires_in: parseInt(params.get("expires_in") || "0"),
+ refresh_token: params.get("refresh_token"),
+ token_type: params.get("token_type"),
+ provider_token: params.get("provider_token"),
+ };
+
+ return data;
+ };
return (
<KeyboardAvoidingView
...
>
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
<VStack safeAreaTop padding={4} flex={1}>
<VStack space={4} marginTop={5} width="full" flex={1}>
...
+ <Button
+ isDisabled={loading}
+ onPress={() => onSignInWithGoogle()}
+ marginBottom={5}
+ >
+ {loading ? "Loading..." : "Sign in with Google"}
+ </Button>
</VStack>
</VStack>
</ScrollView>
</KeyboardAvoidingView>
);
};
export default LoginScreen;
In the “Redirect URLs” section, click the “Add URL”.

Add your custom scheme.
If you are still here, congrats! Now you have an app with Social login.
It's worth mentioning that Supabase offers support for numerous providers, so if you require additional options, they have you covered.
By following the steps outlined in this article, you should be able to easily add more providers to your app. While each provider may have a few specific steps to follow, Supabase's documentation serves as an excellent starting point. To delve deeper, you can find more information here
Once you get the tokens to interact with each provider, you should be able to update the Supabase provider to get the login URL. The rest of the flow should be reusable as is.
I’ll probably cover more about this in the future, so if you have any questions or require additional assistance, please do not hesitate to reach out.