> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shipnative.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Mock Services

> Develop without backend credentials

Mock services activate automatically when API keys are missing. Add credentials via `yarn setup` to use real services - no code changes needed.

## How It Works

```typescript theme={null}
// Backend mock activates based on provider and credentials
export const USE_MOCK_SUPABASE = __DEV__ && isSupabase && !process.env.EXPO_PUBLIC_SUPABASE_URL
export const USE_MOCK_CONVEX = __DEV__ && isConvex && !process.env.EXPO_PUBLIC_CONVEX_URL

// RevenueCat also detects placeholder values like "your-ios-key"
// This prevents SDK credential errors when using .env.example values
const isPlaceholderKey = (key) => !key || key.startsWith("your-")
```

> [!NOTE]
>
> Placeholder values like `your-ios-key` from `.env.example` will also trigger mock mode. This prevents SDK credential errors - you can safely copy `.env.example` to `.env` and the app will work in mock mode.

## Available Mocks

| Service | Mock Behavior |
| - | - |
| **Supabase** | Auth, database, storage, realtime - all in-memory |
| **Convex** | Auth, queries, mutations - all in-memory |
| **PostHog** | Events logged to console, feature flags return false |
| **Sentry** | Errors logged to console |
| **RevenueCat** | Purchases always succeed, dev menu toggle for pro status |

***

## Backend Mocks

> [tab] Supabase
>
> Full simulation of auth, database, storage, and realtime.
>
> ```typescript theme={null}
> import { supabase } from '@/services/supabase'
>
> // Same code works with mock or real Supabase
> await supabase.auth.signInWithPassword({
>   email: 'test@example.com',
>   password: 'password'
> })
>
> const { data } = await supabase
>   .from('posts')
>   .select('*')
>   .eq('author_id', 'user-123')
>
> await supabase.storage
>   .from('avatars')
>   .upload('avatar.jpg', file)
> ```
>
> ### Test Accounts
>
> ```typescript theme={null}
> { email: 'demo@shipnative.app', password: 'demo123' }
> { email: 'test@shipnative.app', password: 'test123' }
> ```
>
> ### Testing Utilities
>
> ```typescript theme={null}
> import { mockSupabaseHelpers } from '@/services/mocks/supabase'
>
> // Seed test data
> mockSupabaseHelpers.seedTable('posts', [
>   { id: 1, title: 'Test Post', author_id: 'user-123' },
> ])
>
> // Clear all mock data
> mockSupabaseHelpers.clearAll()
> ```

> [tab] Convex
>
> Full simulation of auth, queries, and mutations.
>
> ```typescript theme={null}
> import { useConvexAuth } from '@/hooks/convex'
> import { useQuery, useMutation } from '@/hooks/convex'
>
> // Auth works the same in mock mode
> const { signInWithPassword, isAuthenticated } = useConvexAuth()
>
> await signInWithPassword('test@example.com', 'password')
>
> // Queries and mutations work with mock data
> const posts = useQuery(api.posts.list)
> const createPost = useMutation(api.posts.create)
> ```
>
> ### Test Accounts
>
> ```typescript theme={null}
> { email: 'demo@shipnative.app', password: 'demo123' }
> { email: 'test@shipnative.app', password: 'test123' }
> ```
>
> ### Testing Utilities
>
> ```typescript theme={null}
> import { mockConvexHelpers } from '@/services/mocks/convex'
>
> // Seed test data
> mockConvexHelpers.seedTable('posts', [
>   { _id: 'post-1', title: 'Test Post', authorId: 'user-123' },
> ])
>
> // Clear all mock data
> mockConvexHelpers.clearAll()
> ```

***

## Other Service Mocks

### RevenueCat

```typescript theme={null}
import { mockRevenueCat } from '@/services/mocks/revenueCat'

// Toggle pro status for testing
mockRevenueCat.setProStatus(true)

// Or use the Dev Menu (Cmd+D / Cmd+M)
```

### PostHog

Events logged to console with `[MockPostHog]` prefix. Feature flags return `false` by default.

### Sentry

Errors logged to console with `[MockSentry]` prefix instead of being sent to Sentry.

***

## Console Logging

All mock operations log to console:

```
[MockSupabase] Sign in: user@example.com
[MockConvex] Query: api.posts.list
[MockPostHog] Event: button_clicked
[MockRevenueCat] Purchase: pro_monthly
```

***

## Limitations

* Data clears on app restart
* Security policies (RLS, function auth) not enforced
* Network performance not simulated
* Realtime subscriptions simulated locally

For production testing, connect real services via `yarn setup`.

***

## Switching to Real Services

```bash theme={null}
yarn setup
```

The wizard prompts for credentials. Once configured, the app automatically uses real services - no code changes needed.

You can also manually set environment variables in `apps/app/.env`:

> [tab] Supabase
>
> ```bash theme={null}
> EXPO_PUBLIC_BACKEND_PROVIDER=supabase
> EXPO_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
> EXPO_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your-key
> ```

> [tab] Convex
>
> ```bash theme={null}
> EXPO_PUBLIC_BACKEND_PROVIDER=convex
> EXPO_PUBLIC_CONVEX_URL=https://your-project.convex.cloud
> ```

Restart Metro after changing environment variables: `yarn start --clear`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.