Auth

Use Supabase Auth with React Native

Learn how to use Supabase Auth with React Native


1

Create a new Supabase project

Launch a new project in the Supabase Dashboard.

Your new database has a table for storing your users. You can see that this table is currently empty by running some SQL in the SQL Editor.

SQL_EDITOR

_10
select * from auth.users;

2

Create a React app

Create a React app using the create-expo-app command.

Terminal

_10
npx create-expo-app -t expo-template-blank-typescript my-app

3

Install the Supabase client library

Install supabase-js and the required dependencies.

Terminal

_10
cd my-app && npx expo install @supabase/supabase-js @react-native-async-storage/async-storage @rneui/themed react-native-url-polyfill

4

Set up your login component

Create a helper file lib/supabase.ts that exports a Supabase client using your Project URL and public API (anon) key.

lib/supabase.ts

_29
import { AppState } from 'react-native'
_29
import 'react-native-url-polyfill/auto'
_29
import AsyncStorage from '@react-native-async-storage/async-storage'
_29
import { createClient } from '@supabase/supabase-js'
_29
_29
const supabaseUrl = YOUR_REACT_NATIVE_SUPABASE_URL
_29
const supabaseAnonKey = YOUR_REACT_NATIVE_SUPABASE_ANON_KEY
_29
_29
export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
_29
auth: {
_29
storage: AsyncStorage,
_29
autoRefreshToken: true,
_29
persistSession: true,
_29
detectSessionInUrl: false,
_29
},
_29
})
_29
_29
// Tells Supabase Auth to continuously refresh the session automatically
_29
// if the app is in the foreground. When this is added, you will continue
_29
// to receive `onAuthStateChange` events with the `TOKEN_REFRESHED` or
_29
// `SIGNED_OUT` event if the user's session is terminated. This should
_29
// only be registered once.
_29
AppState.addEventListener('change', (state) => {
_29
if (state === 'active') {
_29
supabase.auth.startAutoRefresh()
_29
} else {
_29
supabase.auth.stopAutoRefresh()
_29
}
_29
})

5

Create a login component

Let's set up a React Native component to manage logins and sign ups.

components/Auth.tsx

_83
import React, { useState } from 'react'
_83
import { Alert, StyleSheet, View } from 'react-native'
_83
import { supabase } from '../lib/supabase'
_83
import { Button, Input } from '@rneui/themed'
_83
_83
export default function Auth() {
_83
const [email, setEmail] = useState('')
_83
const [password, setPassword] = useState('')
_83
const [loading, setLoading] = useState(false)
_83
_83
async function signInWithEmail() {
_83
setLoading(true)
_83
const { error } = await supabase.auth.signInWithPassword({
_83
email: email,
_83
password: password,
_83
})
_83
_83
if (error) Alert.alert(error.message)
_83
setLoading(false)
_83
}
_83
_83
async function signUpWithEmail() {
_83
setLoading(true)
_83
const {
_83
data: { session },
_83
error,
_83
} = await supabase.auth.signUp({
_83
email: email,
_83
password: password,
_83
})
_83
_83
if (error) Alert.alert(error.message)
_83
if (!session) Alert.alert('Please check your inbox for email verification!')
_83
setLoading(false)
_83
}
_83
_83
return (
_83
<View style={styles.container}>
_83
<View style={[styles.verticallySpaced, styles.mt20]}>
_83
<Input
_83
label="Email"
_83
leftIcon={{ type: 'font-awesome', name: 'envelope' }}
_83
onChangeText={(text) => setEmail(text)}
_83
value={email}
_83
placeholder="email@address.com"
_83
autoCapitalize={'none'}
_83
/>
_83
</View>
_83
<View style={styles.verticallySpaced}>
_83
<Input
_83
label="Password"
_83
leftIcon={{ type: 'font-awesome', name: 'lock' }}
_83
onChangeText={(text) => setPassword(text)}
_83
value={password}
_83
secureTextEntry={true}
_83
placeholder="Password"
_83
autoCapitalize={'none'}
_83
/>
_83
</View>
_83
<View style={[styles.verticallySpaced, styles.mt20]}>
_83
<Button title="Sign in" disabled={loading} onPress={() => signInWithEmail()} />
_83
</View>
_83
<View style={styles.verticallySpaced}>
_83
<Button title="Sign up" disabled={loading} onPress={() => signUpWithEmail()} />
_83
</View>
_83
</View>
_83
)
_83
}
_83
_83
const styles = StyleSheet.create({
_83
container: {
_83
marginTop: 40,
_83
padding: 12,
_83
},
_83
verticallySpaced: {
_83
paddingTop: 4,
_83
paddingBottom: 4,
_83
alignSelf: 'stretch',
_83
},
_83
mt20: {
_83
marginTop: 20,
_83
},
_83
})

6

Add the Auth component to your app

Add the Auth component to your App.tsx file. If the user is logged in, print the user id to the screen.

App.tsx

_28
import 'react-native-url-polyfill/auto'
_28
import { useState, useEffect } from 'react'
_28
import { supabase } from './lib/supabase'
_28
import Auth from './components/Auth'
_28
import Account from './components/Account'
_28
import { View, Text } from 'react-native'
_28
import { Session } from '@supabase/supabase-js'
_28
_28
export default function App() {
_28
const [session, setSession] = useState<Session | null>(null)
_28
_28
useEffect(() => {
_28
supabase.auth.getSession().then(({ data: { session } }) => {
_28
setSession(session)
_28
})
_28
_28
supabase.auth.onAuthStateChange((_event, session) => {
_28
setSession(session)
_28
})
_28
}, [])
_28
_28
return (
_28
<View>
_28
<Auth />
_28
{session && session.user && <Text>{session.user.id}</Text>}
_28
</View>
_28
)
_28
}

7

Start the app

Start the app, and follow the instructions in the terminal.

Terminal

_10
npm start