DEV Community 👩‍💻👨‍💻

Cover image for How to Use Supabase Apple OAuth in React Native
Dan Curtis
Dan Curtis

Posted on

How to Use Supabase Apple OAuth in React Native

Supabase combined with NextJS or Expo makes spinning up a side project in a few hours possible.

Supabase recently added a tutorial for Expo and support for Apple OAuth authentication. However, Apple OAuth does not work out of the box with Expo and Supabase. So I figured I'd write this article and create a GitHub template.

GIF of Sign in with Apple in template

Supabase and Expo

I followed Supabase's Expo quickstart to get basic authentication working in Expo. The quickstart does not mentioned AsyncStorage which is required in lib/supabase.js to get it working.

My final code:

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

// https://reactnative.dev/docs/security#storing-sensitive-info
import { supabaseUrl, supabaseAnonKey } from './supabase-keys';

export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
  localStorage: AsyncStorage,
  detectSessionInUrl: false
});
Enter fullscreen mode Exit fullscreen mode

Supabase Apple OAuth with Expo

Next I followed Supabase's tutorial for Apple authentication. I tried to use Supabase's sign in method onClick in my React Native auth component, which doesn't work:

const { user, session, error } = await supabase.auth.signIn({
  provider: 'apple'
});
Enter fullscreen mode Exit fullscreen mode

The user/session/error all will be null. I was a bit worried Apple OAuth on mobile wouldn't be supported by Supabase's Go True library, but I stumbled upon a PR which adds support Fix: Add id_token grant flow

Instead of using Apple as the provider I decided to use Expo's authentication library to get a token and then pass that to Supabase:

import { startAsync, makeRedirectUri } from 'expo-auth-session';

import { supabase } from '../lib/supabase';
import { supabaseUrl } from '../lib/supabase-keys';

const signInWithApple = async () => {
    const returnUrl = makeRedirectUri({ useProxy: false });
    const provider = 'apple';
    const authUrl = `${supabaseUrl}/auth/v1/authorize?provider=${provider}&redirect_to=${returnUrl}`;

    const response = await startAsync({ authUrl, returnUrl });

    if (!response || !response.params?.refresh_token) {
      return;
    }

    await supabase.auth.signIn({
      refreshToken: response.params.refresh_token
    });
};
Enter fullscreen mode Exit fullscreen mode

The full code is available on GitHub. Apple OAuth with Supabase and support for React Native is relatively new. Feedback is always welcome if there's a better way of doing things.

Top comments (0)

Visualizing Promises and Async/Await 🤯

async await

☝️ Check out this all-time classic DEV post