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

# Apple Sign In

> Set up Sign in with Apple for your iOS app

# Apple Sign In

Sign in with Apple lets users authenticate with their Apple ID using Face ID or Touch ID. It's fast, secure, and familiar to iOS users.

***

## App Store Requirements

<Warning>
  **Read this before submitting your app.** Apple has strict guidelines for Sign in with Apple that can cause your app to be rejected.
</Warning>

### Rule 1: Apple Sign In is Required if You Have Other Social Login

If your app offers **any** third-party sign-in (Google, Facebook, Twitter, etc.), you **must** also offer Sign in with Apple. This is Apple's App Store Review Guideline 4.8.

```
❌ Only Google Sign In → REJECTED
✅ Google Sign In + Apple Sign In → APPROVED
✅ Only Email/Password → APPROVED (no social login)
✅ Only Apple Sign In → APPROVED
```

### Rule 2: Don't Ask for Name After Apple Sign In

If you ask users for their name **after** they sign in with Apple, your app will likely be rejected. Apple provides the user's name during authentication — you must use that, not ask again.

```
❌ Apple Sign In → "What's your name?" form → REJECTED
✅ Apple Sign In → Use name from Apple response → APPROVED
```

The kit handles this automatically by saving the name to user metadata.

### Rule 3: Name is Only Provided on First Sign-In

Apple only sends the user's full name on the **first** sign-in. All subsequent sign-ins return `null` for the name fields. This is by design.

| Sign-In      | Full Name  | Email                  |
| ------------ | ---------- | ---------------------- |
| First time   | ✅ Provided | ✅ Provided (or hidden) |
| Second+ time | ❌ null     | ✅ Provided             |

**The kit handles this automatically** — it saves the name to Supabase user metadata on first sign-in, so you can always retrieve it later.

***

## How to Test Name Retrieval Again

During development, you may want to test the first sign-in flow multiple times. To do this, you need to revoke your app's access:

<Steps>
  <Step title="Open iPhone Settings">
    Go to **Settings** on your iPhone or Simulator
  </Step>

  <Step title="Tap your Apple ID">
    Tap your name at the top of Settings
  </Step>

  <Step title="Go to Sign-In & Security">
    Tap **Sign-In & Security** (or "Password & Security" on older iOS)
  </Step>

  <Step title="Find Sign in with Apple">
    Tap **Apps Using Your Apple ID** (or "Apps Using Apple ID")
  </Step>

  <Step title="Find your app">
    Look for your app in the list. In development, it may appear as:

    * `Expo Go` (if testing in Expo Go)
    * Your app's name (if using development build)
  </Step>

  <Step title="Stop using Apple ID">
    Tap your app, then tap **Stop Using Apple ID**

    Confirm when prompted
  </Step>
</Steps>

Next time you sign in with Apple in your app, it will be treated as a first sign-in and Apple will provide the full name again.

***

## Overview

Setting up Apple Sign In for native iOS requires:

1. **Supabase Dashboard** — Add your bundle ID to the Apple provider
2. **Apple Developer Console** — Enable Sign in with Apple capability
3. **Your App** — Use the `signInWithApple()` function

**Time required:** \~15 minutes

<Note>
  **No secret key required for native iOS.** Unlike web OAuth, native Sign in with Apple uses the identity token directly. You don't need to create a Services ID or signing key.
</Note>

***

## Part 1: Supabase Dashboard

### Add Your Bundle ID

<Steps>
  <Step title="Open Auth settings">
    Go to your Supabase project dashboard

    Navigate to **Authentication → Providers**
  </Step>

  <Step title="Find Apple provider">
    Click on **Apple** to expand the settings
  </Step>

  <Step title="Add Client IDs">
    In the **Client IDs** field, add your app's bundle identifier(s):

    ```
    com.yourcompany.yourapp
    ```

    If you have multiple build variants, add them all:

    ```
    com.yourcompany.yourapp
    com.yourcompany.yourapp.dev
    com.yourcompany.yourapp.preview
    ```
  </Step>

  <Step title="Testing with Expo Go">
    If testing with Expo Go, also add:

    ```
    host.exp.Exponent
    ```
  </Step>

  <Step title="Save">
    Click **Save**
  </Step>
</Steps>

<Warning>
  **Common mistake:** Forgetting to add `host.exp.Exponent` when testing with Expo Go. This will cause "Invalid client\_id" errors.
</Warning>

***

## Part 2: Apple Developer Console

### Enable Sign in with Apple Capability

<Steps>
  <Step title="Open your App ID">
    Go to [developer.apple.com/account/resources/identifiers](https://developer.apple.com/account/resources/identifiers)

    Click on your app's identifier (e.g., `com.yourcompany.yourapp`)
  </Step>

  <Step title="Enable the capability">
    Scroll down to **Capabilities**

    Check the box next to **Sign in with Apple**

    Click **Save**
  </Step>
</Steps>

That's it for native iOS! No Services ID or signing key needed.

***

## Part 3: App Configuration

### Step 1: Add the Expo Plugin

Ensure `expo-apple-authentication` is in your `app.json` plugins:

```json theme={null}
{
  "expo": {
    "plugins": [
      "expo-apple-authentication"
    ]
  }
}
```

### Step 2: Enable in App Config

Update `config/app.config.ts`:

```typescript theme={null}
auth: {
  mode: 'anonymous', // or 'required'
  providers: {
    apple: true, // Enable Apple Sign In
    google: false,
    email: false,
  },
}
```

### Step 3: Use in Your App

The kit provides a ready-to-use function:

```typescript theme={null}
import { signInWithApple } from '@/lib/auth';

try {
  const { user, session } = await signInWithApple();
  console.log('Signed in:', user.id);
  
  // Full name is automatically saved to user metadata
  console.log('Name:', user.user_metadata?.full_name);
} catch (error) {
  if (error.message.includes('ERR_REQUEST_CANCELED')) {
    // User cancelled - don't show error
    return;
  }
  console.error('Apple sign in failed:', error);
}
```

Or use the pre-built component:

```typescript theme={null}
import { SocialAuthButtons } from '@/components/auth';

<SocialAuthButtons
  showApple={true}
  showGoogle={false}
  onSuccess={() => router.replace('/(main)')}
  onError={(err) => Alert.alert('Error', err.message)}
/>
```

***

## How the Kit Handles the Name

The `signInWithApple()` function automatically handles Apple's name behavior:

```typescript theme={null}
// This happens inside signInWithApple()
if (credential.fullName) {
  const nameParts = [];
  if (credential.fullName.givenName) nameParts.push(credential.fullName.givenName);
  if (credential.fullName.middleName) nameParts.push(credential.fullName.middleName);
  if (credential.fullName.familyName) nameParts.push(credential.fullName.familyName);

  const fullName = nameParts.join(' ');

  if (fullName) {
    await supabase.auth.updateUser({
      data: {
        full_name: fullName,
        given_name: credential.fullName.givenName,
        family_name: credential.fullName.familyName,
      },
    });
  }
}
```

### Retrieving the Name Later

After the user signs in, you can get their name from user metadata:

```typescript theme={null}
import { useAuth } from '@/contexts/auth-context';
import { getUserFullName } from '@/lib/auth';

const { user } = useAuth();

// Get full name
const fullName = getUserFullName(user);
// or
const fullName = user?.user_metadata?.full_name;

// Get individual name parts
const givenName = user?.user_metadata?.given_name;
const familyName = user?.user_metadata?.family_name;
```

***

## Testing

### With Expo Go

You can test Apple Sign In in Expo Go on a physical iOS device:

1. Make sure `host.exp.Exponent` is in your Supabase Client IDs
2. Run `npx expo start`
3. Open in Expo Go on your iPhone
4. Test Sign in with Apple

### With Development Build

For the most accurate testing:

```bash theme={null}
eas build --platform ios --profile development
```

Install the build on your device and test.

### On Simulator

Apple Sign In works on the iOS Simulator, but:

* You must be signed into an Apple ID in the Simulator's Settings
* The Simulator must be iOS 13+

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="'Invalid client_id' error">
    Your bundle ID is not in Supabase's Client IDs list.

    * Check **Authentication → Providers → Apple → Client IDs**
    * Add your exact bundle ID (case-sensitive)
    * If using Expo Go, add `host.exp.Exponent`
  </Accordion>

  <Accordion title="Full name is null">
    Apple only provides the name on the **first** sign-in.

    * If you've signed in before, the name was already provided
    * Check `user.user_metadata.full_name` — it should be saved
    * To test again, revoke app access in iPhone Settings (see above)
  </Accordion>

  <Accordion title="Button doesn't appear">
    * Apple Sign In only works on iOS
    * Check `isAppleSignInAvailable()` returns true
    * Ensure you're on iOS 13+
  </Accordion>

  <Accordion title="'ERR_REQUEST_CANCELED' error">
    This means the user cancelled the sign-in. This is not an error to display to the user.

    The kit's `SocialAuthButtons` handles this automatically.
  </Accordion>

  <Accordion title="App rejected for name input after Apple Sign In">
    You cannot ask users to enter their name after Apple Sign In.

    * Use the name from Apple's response
    * The kit saves it automatically to `user.user_metadata.full_name`
    * If the user chose to hide their name, respect that
  </Accordion>
</AccordionGroup>

***

## What Users See

When a user taps "Sign in with Apple":

1. iOS shows a native Apple authentication sheet
2. User authenticates with Face ID, Touch ID, or password
3. User can choose to share or hide their email
4. User can edit the name Apple will share (first time only)
5. App receives the identity token and signs in

<Tip>
  Apple provides a unique, stable user ID even if the user hides their email. You can always identify returning users.
</Tip>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Google OAuth" icon="google" href="/modules/auth-google">
    Add Google sign-in (remember: requires Apple Sign In too)
  </Card>

  <Card title="Email + Password" icon="envelope" href="/modules/auth-email">
    Add traditional email authentication
  </Card>
</CardGroup>
