{"id":33287059,"url":"https://github.com/yultyyev/better-auth-firebase-auth","last_synced_at":"2026-04-20T23:04:44.089Z","repository":{"id":323989835,"uuid":"1095488710","full_name":"yultyyev/better-auth-firebase-auth","owner":"yultyyev","description":"Firebase Authentication plugin for Better Auth","archived":false,"fork":false,"pushed_at":"2025-11-13T07:20:18.000Z","size":101,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-13T08:34:03.236Z","etag":null,"topics":["authentication","better-auth","firebase","firebase-auth","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yultyyev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-11-13T05:45:37.000Z","updated_at":"2025-11-13T07:12:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/yultyyev/better-auth-firebase-auth","commit_stats":null,"previous_names":["yultyyev/better-auth-firebase-auth"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/yultyyev/better-auth-firebase-auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yultyyev%2Fbetter-auth-firebase-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yultyyev%2Fbetter-auth-firebase-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yultyyev%2Fbetter-auth-firebase-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yultyyev%2Fbetter-auth-firebase-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yultyyev","download_url":"https://codeload.github.com/yultyyev/better-auth-firebase-auth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yultyyev%2Fbetter-auth-firebase-auth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":284920933,"owners_count":27084941,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-17T02:00:06.431Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","better-auth","firebase","firebase-auth","typescript"],"created_at":"2025-11-17T17:05:58.396Z","updated_at":"2026-04-20T23:04:44.078Z","avatar_url":"https://github.com/yultyyev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# better-auth-firebase-auth\n\n[![npm version](https://img.shields.io/npm/v/better-auth-firebase-auth.svg)](https://www.npmjs.com/package/better-auth-firebase-auth)\n[![CI](https://github.com/yultyyev/better-auth-firebase-auth/actions/workflows/release.yml/badge.svg)](https://github.com/yultyyev/better-auth-firebase-auth/actions)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](./LICENSE)\n\n**Firebase Authentication plugin for Better Auth.** Integrate Firebase Auth with Better Auth, allowing users to authenticate using Firebase Auth and create Better Auth sessions.\n\n- **Install:** `pnpm add better-auth-firebase-auth firebase-admin firebase better-auth`\n\n## Why Firebase Auth?\n\nFirebase Authentication provides several advantages when integrated with Better Auth:\n\n- **🔥 Built-in Email Service** - Password reset emails, email verification, and account management emails work out of the box. No need to set up SendGrid, Resend, or other email providers.\n- **🌍 Global Infrastructure** - Firebase Auth is backed by Google's infrastructure, ensuring high availability and low latency worldwide.\n- **🔐 Battle-Tested Security** - Industry-standard OAuth flows and security best practices built-in.\n- **📱 Multi-Platform SDKs** - Consistent authentication across web, iOS, and Android applications.\n- **🎨 Customizable Email Templates** - Easily customize email templates directly in the Firebase Console.\n- **🚀 Quick Setup** - Get authentication working in minutes without managing your own auth infrastructure.\n\n**Use Case:** Perfect for applications that want robust authentication with email functionality without the complexity of setting up and maintaining email infrastructure.\n\n---\n\n## Installation\n\n# npm\n\n```bash\nnpm install better-auth-firebase-auth firebase-admin firebase better-auth\n```\n\n# pnpm\n\n```bash\npnpm add better-auth-firebase-auth firebase-admin firebase better-auth\n```\n\n# yarn\n\n```bash\nyarn add better-auth-firebase-auth firebase-admin firebase better-auth\n```\n\n# bun\n\n```bash\nbun add better-auth-firebase-auth firebase-admin firebase better-auth\n```\n\n## Better Auth Compatibility\n\nThis package supports both older and newer Better Auth releases for hook middleware imports:\n\n- **Preferred in Better Auth v1.5+:** `createAuthMiddleware` from `better-auth/api`\n- **Legacy in older releases:** `createAuthMiddleware` from `better-auth/plugins`\n\nTo keep integration stable across versions, this plugin resolves `createAuthMiddleware` from `better-auth/api` first and falls back to `better-auth/plugins` when needed.\n\nIf you are writing your own Better Auth plugin code, prefer:\n\n```ts\nimport { createAuthMiddleware } from \"better-auth/api\";\n```\n\n## Import Paths\n\nTo prevent bundling issues where client-side code tries to include server-side dependencies (like `firebase-admin`), the package provides separate export paths:\n\n### Client-side (React components, browser code)\n\n```ts\nimport { firebaseAuthClientPlugin } from \"better-auth-firebase-auth/client\";\n```\n\nUse this import in client components, browser-only code, or anywhere the code will run in the browser. This ensures bundlers don't try to include `firebase-admin`.\n\n### Server-side (API routes, server components)\n\n```ts\nimport { firebaseAuthPlugin } from \"better-auth-firebase-auth/server\";\n```\n\nUse this import in API routes, server-side code, or server components where Node.js is available.\n\n### Main export (backward compatibility)\n\n```ts\nimport { firebaseAuthPlugin, firebaseAuthClientPlugin } from \"better-auth-firebase-auth\";\n```\n\nThe main entry point still exports both plugins for backward compatibility, but using the specific paths above is recommended to avoid bundling issues.\n\n## Features\n\n- ✅ Client-side and server-side token generation modes\n- ✅ Optional override of Better Auth's built-in email/password flow\n- ✅ Password reset functionality with email verification\n- ✅ Server-side only mode (hidden endpoints, all auth through hooks)\n- ✅ Sign in with Google\n- ✅ Sign in with email/password\n- ✅ Full TypeScript support\n\n## Supported Authentication Methods\n\nThis plugin currently supports the following Firebase Authentication methods:\n\n### ✅ Currently Supported\n\n- **Google Sign-In** - OAuth provider (`signInWithGoogle`)\n- **Email/Password** - Email-based authentication (`signInWithEmail`)\n  - Sign up with email/password\n  - Sign in with email/password\n  - Password reset flow with email verification\n  - Custom reset URLs\n\n### ❌ Not Yet Supported\n\nThe following Firebase Auth providers are available in Firebase but not yet implemented in this plugin:\n\n**Social Providers:**\n- Facebook\n- GitHub\n- Twitter/X\n- Microsoft\n- Apple\n- Yahoo\n- LinkedIn\n\n**Phone Authentication:**\n- Phone number sign-in with SMS verification\n- Multi-factor authentication (MFA)\n\n**Other Methods:**\n- Anonymous authentication\n- Custom authentication tokens\n- SAML/OpenID Connect providers\n- Game Center (iOS)\n- Play Games (Android)\n\n**Note:** You can still use these providers directly with the Firebase Auth SDK in your application, but they won't automatically create Better Auth sessions. Contributions to add support for additional providers are welcome! See the [Contributing](#contributing) section.\n\n## Usage\n\n### Client-side token generation (default)\n\n**Server-side setup (API routes, `lib/auth.ts`):**\n\n```ts\nimport { betterAuth } from \"better-auth\";\nimport { firebaseAuthPlugin } from \"better-auth-firebase-auth/server\";\nimport { getAuth } from \"firebase-admin/auth\";\n\nexport const auth = betterAuth({\n  plugins: [\n    firebaseAuthPlugin({\n      useClientSideTokens: true, // Client generates Firebase tokens\n      firebaseAdminAuth: getAuth(), // Firebase Admin SDK instance\n    }),\n  ],\n});\n```\n\n**Client-side setup (React components, `lib/auth-client.ts`):**\n\n```ts\nimport { createAuthClient } from \"better-auth/react\";\nimport { firebaseAuthClientPlugin } from \"better-auth-firebase-auth/client\";\n\nexport const authClient = createAuthClient({\n  plugins: [\n    firebaseAuthClientPlugin({\n      // Optional: Add Firebase client config for additional features\n    }),\n  ],\n});\n```\n\n### Server-side token generation\n\n**Server-side setup (API routes, `lib/auth.ts`):**\n\n```ts\nimport { betterAuth } from \"better-auth\";\nimport { firebaseAuthPlugin } from \"better-auth-firebase-auth/server\";\nimport { getAuth } from \"firebase-admin/auth\";\nimport type { FirebaseOptions } from \"firebase/app\";\n\nconst firebaseConfig: FirebaseOptions = {\n  apiKey: process.env.FIREBASE_API_KEY!,\n  authDomain: process.env.FIREBASE_AUTH_DOMAIN!,\n  projectId: process.env.FIREBASE_PROJECT_ID!,\n};\n\nexport const auth = betterAuth({\n  plugins: [\n    firebaseAuthPlugin({\n      useClientSideTokens: false, // Server handles Firebase Auth\n      firebaseAdminAuth: getAuth(),\n      firebaseConfig, // Required for server-side mode\n    }),\n  ],\n});\n```\n\n**Client-side setup (React components, `lib/auth-client.ts`):**\n\n```ts\nimport { createAuthClient } from \"better-auth/react\";\nimport { firebaseAuthClientPlugin } from \"better-auth-firebase-auth/client\";\n\nexport const authClient = createAuthClient({\n  plugins: [\n    firebaseAuthClientPlugin({\n      // No Firebase config needed - server handles everything\n    }),\n  ],\n});\n```\n\n## Password Reset\n\n### Firebase Console Setup (Required)\n\nBefore using password reset, configure your Firebase project:\n\n#### 1. Enable Email/Password Authentication\n- Go to [Firebase Console](https://console.firebase.google.com/)\n- Select your project → **Authentication** → **Sign-in method**\n- Enable **Email/Password** provider\n- Click **Save**\n\n#### 2. Add Authorized Domains (CRITICAL for Custom URLs)\n- Go to **Authentication** → **Settings** → **Authorized domains**\n- Add your application domains:\n  - Development: `localhost` (already included by default)\n  - Production: `yourdomain.com`, `www.yourdomain.com`\n- ⚠️ **Important**: Any domain used in `passwordResetUrl` MUST be in this list, or Firebase will reject the request\n\n#### 3. Customize Email Template (Optional)\n- Go to **Authentication** → **Templates** → **Password reset**\n- Customize the email subject, body, and sender name\n- The email will contain a link to your `passwordResetUrl` with the reset code\n\n### Plugin Configuration\n\n```ts\nimport { betterAuth } from \"better-auth\";\nimport { firebaseAuthPlugin } from \"better-auth-firebase-auth/server\";\n\nexport const auth = betterAuth({\n  plugins: [\n    firebaseAuthPlugin({\n      firebaseConfig: {\n        apiKey: process.env.FIREBASE_API_KEY!,\n        authDomain: process.env.FIREBASE_AUTH_DOMAIN!,\n        projectId: process.env.FIREBASE_PROJECT_ID!,\n      },\n      passwordResetUrl: \"https://myapp.com/reset-password\", // Your custom reset page\n      // OR omit passwordResetUrl to use Firebase's default URL\n    }),\n  ],\n});\n```\n\n**Note**: If `passwordResetUrl` is not provided, Firebase uses its default URL (`https://YOUR_PROJECT.firebaseapp.com/__/auth/action`), which works without any additional setup but doesn't match your app's branding.\n\n### Password Reset Flow\n\n#### Step 1: Request Password Reset\n\n```typescript\nawait authClient.sendPasswordReset({ \n  email: \"user@example.com\" \n});\n// User receives email with link like: https://myapp.com/reset-password?oobCode=ABC123\u0026mode=resetPassword\n```\n\n#### Step 2: Extract Code from URL\n\nOn your reset password page (`/reset-password`):\n\n```typescript\nimport { extractOobCodeFromUrl } from \"better-auth-firebase-auth/client\";\n\n// Extracts oobCode from current URL query parameters\nconst oobCode = extractOobCodeFromUrl(); \n\nif (!oobCode) {\n  // Show error: Invalid or missing reset code\n  return;\n}\n```\n\n#### Step 3: Verify Reset Code (Optional but Recommended)\n\n```typescript\ntry {\n  const { valid, email } = await authClient.verifyPasswordResetCode({ \n    oobCode \n  });\n  \n  // Show reset form with email pre-filled\n  console.log(\"Reset password for:\", email);\n} catch (error) {\n  // Show error: Invalid or expired reset code\n}\n```\n\n#### Step 4: Confirm New Password\n\n```typescript\ntry {\n  await authClient.confirmPasswordReset({\n    oobCode,\n    newPassword: \"newSecurePassword123\",\n  });\n  \n  // Success! Redirect to login page\n} catch (error) {\n  // Show error: Failed to reset password\n}\n```\n\n### Complete Example\n\n```tsx\n// app/reset-password/page.tsx\n\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { extractOobCodeFromUrl } from \"better-auth-firebase-auth/client\";\n\nexport default function ResetPasswordPage() {\n  const [oobCode, setOobCode] = useState\u003cstring | null\u003e(null);\n  const [email, setEmail] = useState\u003cstring\u003e(\"\");\n  const [newPassword, setNewPassword] = useState(\"\");\n  const [error, setError] = useState(\"\");\n  const [success, setSuccess] = useState(false);\n\n  useEffect(() =\u003e {\n    const code = extractOobCodeFromUrl();\n    if (!code) {\n      setError(\"Invalid or missing reset code\");\n      return;\n    }\n    setOobCode(code);\n\n    // Verify the code\n    authClient.verifyPasswordResetCode({ oobCode: code })\n      .then(({ email }) =\u003e setEmail(email))\n      .catch(() =\u003e setError(\"Invalid or expired reset code\"));\n  }, []);\n\n  const handleSubmit = async (e: React.FormEvent) =\u003e {\n    e.preventDefault();\n    if (!oobCode) return;\n\n    try {\n      await authClient.confirmPasswordReset({\n        oobCode,\n        newPassword,\n      });\n      setSuccess(true);\n    } catch (err) {\n      setError(\"Failed to reset password\");\n    }\n  };\n\n  if (error) return \u003cdiv\u003eError: {error}\u003c/div\u003e;\n  if (success) return \u003cdiv\u003ePassword reset successful! \u003ca href=\"/login\"\u003eLogin\u003c/a\u003e\u003c/div\u003e;\n\n  return (\n    \u003cform onSubmit={handleSubmit}\u003e\n      \u003ch1\u003eReset Password\u003c/h1\u003e\n      \u003cp\u003eEmail: {email}\u003c/p\u003e\n      \u003cinput\n        type=\"password\"\n        placeholder=\"New password\"\n        value={newPassword}\n        onChange={(e) =\u003e setNewPassword(e.target.value)}\n        required\n      /\u003e\n      \u003cbutton type=\"submit\"\u003eReset Password\u003c/button\u003e\n    \u003c/form\u003e\n  );\n}\n```\n\n### Troubleshooting\n\n**Error: \"Invalid action code\"**\n- The reset link has expired (default: 1 hour)\n- The code has already been used\n- Solution: Request a new password reset email\n\n**Error: \"Unauthorized domain\"**\n- Your `passwordResetUrl` domain is not in Firebase's authorized domains list\n- Solution: Add the domain in Firebase Console → Authentication → Settings → Authorized domains\n\n**Email not received**\n- Check spam/junk folder\n- Verify the email address is registered in Firebase Auth\n- Check Firebase Console → Authentication → Templates for email settings\n\n## Options\n\n```ts\nfirebaseAuthPlugin({\n  useClientSideTokens?: boolean; // Default: true\n  overrideEmailPasswordFlow?: boolean; // Default: false\n  serverSideOnly?: boolean; // Default: false\n  firebaseAdminAuth?: admin.auth.Auth; // Optional\n  firebaseConfig?: FirebaseOptions; // Required for server-side mode\n  passwordResetUrl?: string; // Custom URL for password reset page\n  sessionExpiresInDays?: number; // Default: 7\n});\n```\n\n## Example\n\nSee the [minimal example](./examples/minimal) for a complete Next.js setup demonstrating the plugin usage. That README also explains **build-time defaults** in `lib/auth.ts` (placeholder secret and optional Firebase env) so `next build` can run without a full `.env`.\n\n## FAQ\n\n### What is `better-auth-firebase-auth`?\n\n`better-auth-firebase-auth` is a Better Auth plugin that connects Firebase Authentication to Better Auth sessions. It lets you use Firebase sign-in flows while still using Better Auth for session management and app-level auth features.\n\n### Does this plugin support Google Sign-In and email/password authentication?\n\nYes. The plugin supports Google Sign-In and email/password authentication, including password reset endpoints and helpers. Additional Firebase providers (such as GitHub, Apple, phone auth, and MFA) are not yet implemented in this package.\n\n### How is this different from using Firebase Auth alone?\n\nFirebase Auth handles identity (who the user is), while this plugin bridges Firebase identities into Better Auth users, accounts, and sessions. This is useful when your app already uses Better Auth and you want Firebase providers and Firebase-managed email flows.\n\n### Should I use client-side or server-side token generation?\n\nUse client-side token generation (`useClientSideTokens: true`) for the simplest setup. Use server-side token generation (`useClientSideTokens: false`) when you want the server to handle Firebase client initialization and token exchange logic.\n\n### Can I use this package in a Next.js app?\n\nYes. The package is designed for modern TypeScript apps and works well with Next.js. Use `better-auth-firebase-auth/server` in server code and `better-auth-firebase-auth/client` in browser/client code to avoid bundling issues.\n\n### Does this plugin override Better Auth email/password by default?\n\nNo. `overrideEmailPasswordFlow` is `false` by default. You can opt in to override Better Auth email/password routes when you want Firebase to be the source of truth for those credentials.\n\n## Firestore Adapter\n\nFor storing Better Auth data in Firestore, see [@yultyyev/better-auth-firestore](https://www.npmjs.com/package/@yultyyev/better-auth-firestore):\n\n```bash\nnpm install @yultyyev/better-auth-firestore\n```\n\n```ts\nimport { firestoreAdapter } from \"@yultyyev/better-auth-firestore\";\n\nexport const auth = betterAuth({\n  database: firestoreAdapter(),\n  plugins: [firebaseAuthPlugin({ ... })],\n});\n```\n\n## Contributing\n\nContributions are welcome! Please follow the [Better Auth Contributing Guide](https://www.better-auth.com/docs/reference/contributing) for development setup and code style.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyultyyev%2Fbetter-auth-firebase-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyultyyev%2Fbetter-auth-firebase-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyultyyev%2Fbetter-auth-firebase-auth/lists"}