ashkanahmadi

useSupabaseAuth

Oct 24th, 2025 (edited)
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { supabase } from '@/utils/supabase/supabase'
  2. import { AppState, AppStateStatus } from 'react-native'
  3.  
  4. import type { Session, User } from '@supabase/supabase-js'
  5. import { createContext, useContext, useEffect, useMemo, useState } from 'react'
  6.  
  7. // Tells Supabase Auth to continuously refresh the session automatically if
  8. // the app is in the foreground. When this is added, you will continue to receive
  9. // `onAuthStateChange` events with the `TOKEN_REFRESHED` or `SIGNED_OUT` event
  10. // if the user's session is terminated. This should only be registered once.
  11. // AppState.addEventListener('change', state => {
  12. //   if (state === 'active') {
  13. //     supabase.auth.startAutoRefresh()
  14. //   } else {
  15. //     supabase.auth.stopAutoRefresh()
  16. //   }
  17. // })
  18.  
  19. type AuthContextValue = {
  20.   isAuthLoading: boolean
  21.   isAuthenticated: boolean
  22.   session: Session | null
  23.   user: User | null
  24.   signInWithEmailAndPassword: (email: string, password: string) => Promise<{ data: { user: User | null; session: Session | null } | null; error: any }>
  25.   signOut: () => Promise<{ error: any }>
  26. }
  27.  
  28. const SupabaseAuthContext = createContext<AuthContextValue | null>(null)
  29.  
  30. export default function SupabaseAuthProvider({ children }: { children: React.ReactNode }) {
  31.   const [isAuthLoading, setIsAuthLoading] = useState(false)
  32.   const [session, setSession] = useState<null | Session>(null)
  33.   const [user, setUser] = useState<null | User>(null)
  34.   const isAuthenticated = !!(session && user)
  35.  
  36.   // 1) Initial load + auth change subscription
  37.   useEffect(() => {
  38.     let mounted = true
  39.  
  40.     ;(async () => {
  41.       const { data, error } = await supabase.auth.getSession()
  42.       if (!mounted) return
  43.       if (!error) {
  44.         setSession(data.session ?? null)
  45.         setUser(data.session?.user ?? null)
  46.       }
  47.       setIsAuthLoading(false)
  48.     })()
  49.  
  50.     const { data: sub } = supabase.auth.onAuthStateChange((_event, newSession) => {
  51.       setSession(newSession)
  52.       setUser(newSession?.user ?? null)
  53.     })
  54.  
  55.     return () => {
  56.       mounted = false
  57.       sub?.subscription?.unsubscribe?.()
  58.     }
  59.   }, [])
  60.  
  61.   // 2) Auto refresh while app is active (with cleanup)
  62.   useEffect(() => {
  63.     const handleAppState = (state: AppStateStatus) => {
  64.       if (state === 'active') {
  65.         supabase.auth.startAutoRefresh()
  66.       } else {
  67.         supabase.auth.stopAutoRefresh()
  68.       }
  69.     }
  70.  
  71.     const sub = AppState.addEventListener('change', handleAppState)
  72.     // start immediately if already active
  73.     handleAppState(AppState.currentState)
  74.  
  75.     return () => {
  76.       supabase.auth.stopAutoRefresh()
  77.       sub.remove()
  78.     }
  79.   }, [])
  80.  
  81.   async function signInWithEmailAndPassword(email: string, password: string) {
  82.     // setIsAuthLoading(true)
  83.  
  84.     const { data, error } = await supabase.auth.signInWithPassword({
  85.       email,
  86.       password,
  87.     })
  88.  
  89.     if (data || !error) {
  90.       setSession(data.session)
  91.       setUser(data.user)
  92.     }
  93.     // setIsAuthLoading(false)
  94.  
  95.     return { data, error }
  96.   }
  97.  
  98.   async function signOut() {
  99.     // setIsAuthLoading(true)
  100.  
  101.     const { error } = await supabase.auth.signOut()
  102.  
  103.     if (!error) {
  104.       setSession(null)
  105.       setUser(null)
  106.     }
  107.  
  108.     return { error }
  109.   }
  110.  
  111.   const value = useMemo<AuthContextValue>(
  112.     () => ({
  113.       isAuthLoading,
  114.       isAuthenticated,
  115.       session,
  116.       user,
  117.       signInWithEmailAndPassword,
  118.       signOut,
  119.     }),
  120.     [isAuthLoading, isAuthenticated, session, user]
  121.   )
  122.  
  123.   return <SupabaseAuthContext.Provider value={value}>{children}</SupabaseAuthContext.Provider>
  124. }
  125.  
  126. export const useSupabaseAuth = () => {
  127.   const context = useContext(SupabaseAuthContext)
  128.  
  129.   if (!context) throw new Error('useSupabaseAuth must be used within SupabaseAuthProvider')
  130.  
  131.   return context
  132. }
  133.  
Advertisement
Add Comment
Please, Sign In to add comment