# Social authentication setup

Guide to enable Google, Apple, and Facebook login in your project.

---

## Google Sign-In

### Firebase backend

The CLI handles the technical setup automatically when generating the project:
- Reads the `REVERSED_CLIENT_ID` from `GoogleService-Info.plist`
- Registers the URL scheme in `ios/Runner/Info.plist`
- Writes `lib/google_auth_options.dart` with the Web Client ID
- Registers both `firebaseapp.com` and `web.app` OAuth redirect URIs in Google Cloud (`firebase deploy --only auth`)
- Sets `authDomain` in `firebase_options` to `YOUR_PROJECT.web.app` (same-origin on default Hosting; important in IDE embedded browsers)

**Existing project (created before CLI 1.71.4):** run `kasy oauth-web` in your app folder. It registers both redirect URIs in Google Cloud (`firebase deploy --only auth`) and patches `authDomain`. Use `--no-deploy` for a local `authDomain` patch only.

**What you need to verify once:**

1. [Firebase Console → Authentication → Sign-in method → Google](https://console.firebase.google.com/project/_/authentication/providers) → enable
2. The CLI automatically adds the debug keystore SHA-1 for Android. If you use a new computer or a different keystore, verify with:
```bash
kasy doctor
```

### Supabase backend (no Firebase companion)

Google Sign-In does **not** need a Firebase companion. Push (FCM) is the only reason to create Firebase alongside Supabase.

**Quick mode asks:**
1. Want push? If yes, the CLI creates a Firebase companion (free FCM, no Blaze) and explains that clearly.
2. Want Google? With push: OAuth + Android SHA-1 are automated via the companion. Without push: Web Client ID/Secret paste + the CLI **prints** the debug SHA-1 so you can create an Android OAuth client in the Console (that step is **not** automatic without a companion).

**What is automatic with a companion (push yes):**
- FCM project, Google OAuth mint, SHA-1 on the Firebase Android app, Supabase Auth provider
- **You do not create an Android OAuth client by hand:** Firebase + SHA-1 already wire native Google Sign-In on Android. A manual Android OAuth client in the Console is only for the path **without** a companion (then the CLI prints the SHA-1 for you to paste).

**What is NOT fully automatic (be honest):**
- Creating the **Web** OAuth client in Google Cloud Console (no stable public API) when there is **no** companion
- Registering Android SHA-1 **without** a Firebase companion (CLI extracts and prints; you paste into an Android OAuth client)

**Manual checklist (no companion):** run `kasy google` (prints the guide) or `configure_google_login` in MCP (without credentials, returns the steps).

1. **Separate GCP project** (not the Supabase project). Reuse an existing one or create at [console.cloud.google.com/projectcreate](https://console.cloud.google.com/projectcreate). If "No organization" hits the project quota, pick another org. Inside an org, the Console may **require linking billing** (GCP rule, not Supabase). Linking billing does not mean you will be charged: OAuth in Testing is free.
2. **OAuth branding / consent screen** (Auth Platform → Get started): app name + support email → Audience **External** → contact email (type and press **Enter** to confirm in the list) → accept the policy → **Create**.
3. **Web OAuth client:** [OAuth overview](https://console.cloud.google.com/auth/overview) → **Create OAuth client** → type **Web application**.
4. Under **Authorized redirect URIs**, add:
   `https://YOUR_PROJECT_REF.supabase.co/auth/v1/callback`
5. **Test users** (Testing mode): Audience → add the Gmail you will use to test sign-in.
6. Copy **Client ID** and **Client Secret** with the Console copy button (plain text, never a screenshot). One wrong character becomes `401 invalid_client`. Then run:
```bash
kasy google
```
   This writes `lib/google_auth_options.dart`, enables the Google provider on Supabase Auth, and prints the Android SHA-1.
7. (Optional) iOS OAuth client for native iPhone Sign-In; the command prompts or accepts `--ios-client-id`

With MCP (`create_project`): Google is ON by default (independent of push). With `push=true`, the companion can mint OAuth and register credentials on Supabase Auth. Without push, the scaffold includes Google and the provider is already **Enabled** on Supabase Auth (like Apple); for Client ID/Secret, use `configure_google_login` later (do not ask Google during `create_project`).

### API REST backend

The client can receive IDs via `kasy google` (writes `google_auth_options.dart`). Social login on the server is your API's job (`UnimplementedError` in the template until you implement it).

---

## Apple Sign-In

Requires an [Apple Developer](https://developer.apple.com) account (paid).

### Step 1 — Enable capability on Bundle ID

1. Open [Identifiers](https://developer.apple.com/account/resources/identifiers/list)
2. Select your Bundle ID
3. Enable **Sign In with Apple** → Enable as a primary App ID → **Save**

### Step 2 — Create a key

1. Open [Keys](https://developer.apple.com/account/resources/authkeys/list)
2. Click **+** → enter a name (e.g. `Firebase Sign In with Apple`)
3. Enable **Sign In with Apple** → Configure → select your Bundle ID → Save
4. Register → **download the `.p8` file** (can only be downloaded once — store it safely)
5. Note the **Key ID** (e.g. `6RR89XG535`)

### Step 3 — Create or edit the Services ID (web)

Apple Sign-In **on the web** uses a **Services ID** (`com.company.app.signin`). It is **not** the same as the iOS **App ID** (`com.company.app`). Opening the wrong identifier shows errors or **Configure** won't save.

1. Open [Identifiers](https://developer.apple.com/account/resources/identifiers/list) (**Certificates, Identifiers & Profiles** → **Identifiers**).
   Direct link to Services IDs: [Services IDs list](https://developer.apple.com/account/resources/identifiers/list/serviceId)
2. **Filter (important):** the page defaults to **App IDs** (list shows `com.company.app`). In the top-right table dropdown (**App IDs**), switch to **Services IDs**. Only then you see or create `YOUR_BUNDLE_ID.signin`.
3. If it does not exist yet: click **+** → select **Services IDs** → Continue
4. Fill in:
   - **Description**: `Firebase Sign In with Apple` (or your app name)
   - **Identifier**: `YOUR_BUNDLE_ID.signin` (e.g. `com.company.app.signin`)
5. Register → click the Services ID → enable **Sign In with Apple** → **Configure**
6. **Primary App ID**: your Bundle ID (`com.company.app`)

**Domains and Return URLs depend on the backend:**

| Backend | Domains (no `https://`, comma on one line) | Return URLs (with `https://`, comma on one line) |
| --- | --- | --- |
| **Firebase** | `YOUR_PROJECT.firebaseapp.com, YOUR_PROJECT.web.app` | `https://YOUR_PROJECT.firebaseapp.com/__/auth/handler, https://YOUR_PROJECT.web.app/__/auth/handler` |
| **Supabase** | `YOUR_PROJECT_REF.supabase.co` | `https://YOUR_PROJECT_REF.supabase.co/auth/v1/callback` |

> **Apple portal format:** Domains and Return URLs must be a **comma-separated list on one line** (not one entry per line). Separate lines in the textarea trigger *One or more domains are invalid* and disable **Next**.
>
> Firebase example: `project.firebaseapp.com, project.web.app` and both `__/auth/handler` URLs on one line.
>
> Supabase example: `abcxyz.supabase.co` and `https://abcxyz.supabase.co/auth/v1/callback`

7. **Next** → **Done** → **Continue** → **Save**

### Step 4 — Configure in Firebase

1. Open [Firebase Console → Authentication → Apple](https://console.firebase.google.com/project/_/authentication/providers)
2. Enable the Apple provider
3. Fill in under **OAuth code flow configuration**:
   - **Services ID**: the identifier from Step 3 (e.g. `com.company.app.signin`)
   - **Team ID**: found at [Membership Details](https://developer.apple.com/account#MembershipDetailsCard)
   - **Key ID**: the Key ID from Step 2
   - **Private key**: full content of the `.p8` file, including the `-----BEGIN PRIVATE KEY-----` and `-----END PRIVATE KEY-----` lines
4. **Save**

### Step 5 — Enable capability in Xcode

1. Open `ios/Runner.xcworkspace` in Xcode
2. Target **Runner** → **Signing & Capabilities** → **+ Capability** → add **Sign In with Apple**

> **iOS / macOS**: the Apple button shows automatically once the steps above are done.
>
> **Android**: the Apple button is hidden by design (it needs the paid Services ID web flow and adds little on Android for a SaaS). Leave it hidden.
>
> **Web (Firebase)**: after Steps 1-3, run `kasy apple-web` — it writes the Services ID + Team ID + Key ID + `.p8` into the Firebase Apple provider and turns on `withAppleWebSignin` (which ships `false`). The Services ID needs **both** domains and **both** Return URLs (`firebaseapp.com` and `web.app`). Firebase re-signs the secret itself (never expires). Until you run the command, the Apple button still appears in any browser on an Apple device (iOS, iPadOS, macOS) and shows a setup toast.
>
> **Web (Supabase)**: same Apple Developer steps, then run `kasy apple-web` — it signs the client secret and stores it in Supabase (expires every ~6 months; rerun the command to renew). On the Services ID, **Domain**: `YOUR_PROJECT_REF.supabase.co` and **Return URL**: `https://YOUR_PROJECT_REF.supabase.co/auth/v1/callback` (comma on one line if you add more). Until configured, the Apple button appears in any browser on an Apple device (iOS, iPadOS, macOS) with a setup toast.

---

## Facebook Sign-In

Requires a [Meta for Developers](https://developers.facebook.com) account.

> **Shortcut:** the `kasy facebook` command automates writing the credentials (Info.plist, strings.xml, and the Firebase/Supabase provider) and opens the Meta dashboard. The steps below are what you do on Meta (manual, no API).

### Step 1 — Create an app on Meta

1. Open [Meta for Developers → My Apps](https://developers.facebook.com/apps)
2. Click **Create App** → select **Consumer** → Next
3. Enter the app name → Create App
4. In the app dashboard, note the **App ID** and **Client Token** (Settings → Advanced → Client Token)

### Step 2 — Enable Facebook Login

1. In the Meta app dashboard → Add Product → **Facebook Login** → Set Up → iOS/Android as needed
2. iOS: provide your app's Bundle ID

### Step 3 — iOS: update Info.plist

Edit `ios/Runner/Info.plist` and replace the placeholders:

```xml
<key>FacebookAppID</key>
<string>YOUR_APP_ID</string>
<key>FacebookClientToken</key>
<string>YOUR_CLIENT_TOKEN</string>
<key>FacebookDisplayName</key>
<string>Your app name</string>
```

And the URL scheme (inside `CFBundleURLTypes`):
```xml
<string>fbYOUR_APP_ID</string>
```

### Step 4 — Android: update strings.xml

Edit `android/app/src/main/res/values/strings.xml` and replace the placeholders:

```xml
<string name="facebook_app_id">YOUR_APP_ID</string>
<string name="facebook_client_token">YOUR_CLIENT_TOKEN</string>
```

### Step 5 — Web: add domain in Meta

1. In the Meta app dashboard → Facebook Login → Settings
2. Under **Valid OAuth Redirect URIs**, add:
   - **Firebase backend** (add both):
     - `https://YOUR_PROJECT.firebaseapp.com/__/auth/handler`
     - `https://YOUR_PROJECT.web.app/__/auth/handler`
   - **Supabase backend**: `https://YOUR_PROJECT.supabase.co/auth/v1/callback`
3. Under **Allowed Domains for the JavaScript SDK**, add your app domains (`firebaseapp.com` and `web.app` for Firebase; your web host for Supabase)

Then run `kasy facebook` to write the native files, enable the provider and flip `withFacebookWebSignin`. Until configured, the Facebook button still appears on web with a setup toast.

---

## Supabase

For projects using the Supabase backend, the Apple and Meta setup is identical. What changes is where you register the credentials:

| Provider | Where to configure |
|----------|--------------------|
| Google | Supabase Dashboard → Auth → Providers → Google |
| Apple | Supabase Dashboard → Auth → Providers → Apple (Services ID required) |
| Facebook | Supabase Dashboard → Auth → Providers → Facebook |

For Apple with Supabase, the Services ID **Return URL** must be:
```
https://YOUR_PROJECT.supabase.co/auth/v1/callback
```

### Web in production

The Kasy automated deploy (`kasy new` / `kasy deploy`) only sets `http://localhost:5555` in the Supabase Auth allowed URI list (`uri_allow_list`). That is the port `kasy run --web` uses.

Before publishing your web app to production:

1. Open the Supabase Dashboard → **Authentication → URL Configuration**
2. Add your real domain under **Site URL** and **Redirect URLs** (e.g. `https://yoursite.com` and `https://yoursite.com/**`)
3. Keep `http://localhost:5555` too if you still test locally

Without this, social login (Google, Apple, Facebook) redirects to the wrong domain or fails silently after OAuth.

### Verifying anonymous users in the dashboard

After onboarding or **Continue without account**, the user exists in both `auth.users` and `public.users` (via the `handle_new_user` trigger).

On **Authentication → Users**, anonymous accounts have no email. If the search dropdown is set to **Email address**, the list looks empty or only shows Google/Apple accounts.

1. Switch the dropdown to **Unified search** (or **User ID**)
2. Clear the search box
3. Look for rows with email **-** and provider **Anonymous**
4. The footer **Total: X users** may be higher than visible rows
5. Copy the UID from **Table Editor → users** and search in Auth

More details: [Troubleshooting](https://kasy.dev/docs/referencia/troubleshooting) (*Anonymous user created but missing in Supabase Auth*).

### Why does the Firebase Console show "Authentication" on my Supabase project?

**Only if a Firebase companion exists** (you enabled **push** in Quick, Advanced, or with `kasy add notifications`). Without push there is **no** companion Firebase project and this section does not apply.

When the companion exists: app login, sessions, and users live in **Supabase Auth only**. The companion is **not** your login backend.

**What the companion Firebase project actually does:**
- **Push (FCM)** and native configs (`google-services.json` / `GoogleService-Info.plist`)
- **Remote Config** (when used)
- If Google is also on **with** push: **OAuth automation** (mint Client ID/Secret + SHA-1) and registration on Supabase Auth; Google on Firebase Auth is only temporary and then disabled

**Without push:** Google = Web OAuth in the Console + `kasy google` (no Identity Platform / no companion).

The app follows the [official Supabase Flutter flow](https://supabase.com/docs/guides/auth/social-login/auth-google?platform=flutter): **web** uses `signInWithOAuth`, **iOS/Android** use `google_sign_in` + `signInWithIdToken`.

**Does this cost anything extra?** No. FCM and standard Firebase Auth providers are free; the companion only exists when push is on.
