Skip to main content
Mobile Launcher

Authentication

Supabase Auth Implementation

Authentication

The boilerplate comes with a fully configured Authentication flow using Supabase.

1. The Auth Provider

We wrap the entire app in an AuthProvider (located in src/core/auth/AuthContext.tsx). This provider listens for Supabase session changes.

Tsx
// Inside AuthProvider
useEffect(() => {
  supabase.auth.getSession().then(({ data: { session } }) => {
    setSession(session);
  });

  const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => {
    setSession(session);
  });

  return () => subscription.unsubscribe();
}, []);

2. Using Authentication

Use the useAuth hook to access the current user.

Tsx
// src/features/auth/hooks/use-auth.ts

export const useAuth = () => {
  // Selectors from Redux
  const user = useAppSelector(selectUser);
  const isAuthenticated = useAppSelector(selectIsAuthenticated);
  
  // Actions
  const handleLogin = useCallback(async (credentials) => {
    // ... calls authService.signIn
    // ... dispatches loginSuccess
  }, []);

  return {
    user,
    isAuthenticated,
    login: handleLogin,
    logout: handleLogout,
    // ...
  };
};

Usage Example

Tsx
import { useAuth } from "@/features/auth/hooks/use-auth";

const Profile = () => {
  const { user, logout } = useAuth();

  if (!user) return <Text>Guest</Text>;

  return (
    <Box padding="m">
      <Text variant="header">Hello, {user.email}</Text>
      <Button onPress={logout} title="Sign Out" />
    </Box>
  );
};

3. Protecting Routes

Expo Router allows us to protect groups of routes.

  • (auth) group: Public routes (Login, Signup).
  • (app) group: Private routes (Home, Profile).

In app/_layout.tsx, we check the session state and redirect accordingly.

Tsx
// app/_layout.tsx
useEffect(() => {
  if (!session && inAppGroup) {
    router.replace('/(auth)/login');
  } else if (session && inAuthGroup) {
    router.replace('/(app)/home');
  }
}, [session, segments]);