Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { supabase } from '@/utils/supabase/supabase'
- import { AppState, AppStateStatus } from 'react-native'
- import type { Session, User } from '@supabase/supabase-js'
- import { createContext, useContext, useEffect, useMemo, useState } from 'react'
- // Tells Supabase Auth to continuously refresh the session automatically if
- // the app is in the foreground. When this is added, you will continue to receive
- // `onAuthStateChange` events with the `TOKEN_REFRESHED` or `SIGNED_OUT` event
- // if the user's session is terminated. This should only be registered once.
- // AppState.addEventListener('change', state => {
- // if (state === 'active') {
- // supabase.auth.startAutoRefresh()
- // } else {
- // supabase.auth.stopAutoRefresh()
- // }
- // })
- type AuthContextValue = {
- isAuthLoading: boolean
- isAuthenticated: boolean
- session: Session | null
- user: User | null
- signInWithEmailAndPassword: (email: string, password: string) => Promise<{ data: { user: User | null; session: Session | null } | null; error: any }>
- signOut: () => Promise<{ error: any }>
- }
- const SupabaseAuthContext = createContext<AuthContextValue | null>(null)
- export default function SupabaseAuthProvider({ children }: { children: React.ReactNode }) {
- const [isAuthLoading, setIsAuthLoading] = useState(false)
- const [session, setSession] = useState<null | Session>(null)
- const [user, setUser] = useState<null | User>(null)
- const isAuthenticated = !!(session && user)
- // 1) Initial load + auth change subscription
- useEffect(() => {
- let mounted = true
- ;(async () => {
- const { data, error } = await supabase.auth.getSession()
- if (!mounted) return
- if (!error) {
- setSession(data.session ?? null)
- setUser(data.session?.user ?? null)
- }
- setIsAuthLoading(false)
- })()
- const { data: sub } = supabase.auth.onAuthStateChange((_event, newSession) => {
- setSession(newSession)
- setUser(newSession?.user ?? null)
- })
- return () => {
- mounted = false
- sub?.subscription?.unsubscribe?.()
- }
- }, [])
- // 2) Auto refresh while app is active (with cleanup)
- useEffect(() => {
- const handleAppState = (state: AppStateStatus) => {
- if (state === 'active') {
- supabase.auth.startAutoRefresh()
- } else {
- supabase.auth.stopAutoRefresh()
- }
- }
- const sub = AppState.addEventListener('change', handleAppState)
- // start immediately if already active
- handleAppState(AppState.currentState)
- return () => {
- supabase.auth.stopAutoRefresh()
- sub.remove()
- }
- }, [])
- async function signInWithEmailAndPassword(email: string, password: string) {
- // setIsAuthLoading(true)
- const { data, error } = await supabase.auth.signInWithPassword({
- email,
- password,
- })
- if (data || !error) {
- setSession(data.session)
- setUser(data.user)
- }
- // setIsAuthLoading(false)
- return { data, error }
- }
- async function signOut() {
- // setIsAuthLoading(true)
- const { error } = await supabase.auth.signOut()
- if (!error) {
- setSession(null)
- setUser(null)
- }
- return { error }
- }
- const value = useMemo<AuthContextValue>(
- () => ({
- isAuthLoading,
- isAuthenticated,
- session,
- user,
- signInWithEmailAndPassword,
- signOut,
- }),
- [isAuthLoading, isAuthenticated, session, user]
- )
- return <SupabaseAuthContext.Provider value={value}>{children}</SupabaseAuthContext.Provider>
- }
- export const useSupabaseAuth = () => {
- const context = useContext(SupabaseAuthContext)
- if (!context) throw new Error('useSupabaseAuth must be used within SupabaseAuthProvider')
- return context
- }
Advertisement
Add Comment
Please, Sign In to add comment