workos-migrate-firebase
WorkOS Migration: Firebase
Step 1: Fetch Documentation (BLOCKING)
STOP. Do not proceed until complete.
WebFetch: https://workos.com/docs/migrate/firebase
The migration guide is the source of truth. If this skill conflicts with the guide, follow the guide.
Step 2: Pre-Migration Assessment (Decision Tree)
Map Firebase auth features to WorkOS equivalents:
Current Firebase Auth Feature?
|
+-- Password Auth --> Step 3: Password Hash Import
|
+-- Social Auth (Google/Microsoft/GitHub) --> Step 4: Social Provider Migration
|
+-- Email Link (Passwordless) --> Step 5: Magic Auth Migration
|
+-- OIDC/SAML (Enterprise SSO) --> Step 6: Enterprise Auth Migration
|
+-- Phone Auth --> NOT SUPPORTED (manual user notification required)
Critical: WorkOS supports Firebase's scrypt variant for password hashes. Unlike some systems (e.g., Cognito), Firebase DOES export password hashes via CLI.
Step 3: Password Hash Import
3.1: Export Firebase Hash Parameters
From Firebase Console:
- Navigate to Authentication > Users
- Click the three-dot menu (⋮)
- Select "Export users"
- Note the hash parameters displayed:
base64_signer_keybase64_salt_separatorroundsmem_cost
Store these safely — they are global per Firebase project.
3.2: Export User Data
Run Firebase CLI command:
firebase auth:export users.json --format=json
Verify export:
# Check file exists and contains password hashes
jq '[.users[] | select(.passwordHash != null)] | length' users.json
# If output is 0, users don't have passwords or export failed
Users with passwords will have passwordHash and salt fields.
3.3: Format PHC Hash String
Firebase scrypt → WorkOS PHC format:
$firebase-scrypt$ln={rounds},r={mem_cost}$sk={base64_signer_key}$ss={base64_salt_separator}${salt}${passwordHash}
Parameter mapping:
| Firebase Field | PHC Parameter |
|---|---|
base64_signer_key |
sk |
base64_salt_separator |
ss |
rounds |
ln |
mem_cost |
r |
User's salt |
(raw value) |
User's passwordHash |
(raw value) |
Example transformation:
// Firebase export values (per-project)
const signerKey = 'abc123==';
const saltSeparator = 'xyz789==';
const rounds = 8;
const memCost = 14;
// Per-user values
const userSalt = 'user_salt_base64';
const userHash = 'user_hash_base64';
// WorkOS PHC format
const phcHash = `$firebase-scrypt$ln=${rounds},r=${memCost}$sk=${signerKey}$ss=${saltSeparator}$${userSalt}$${userHash}`;
Critical: All base64 values must preserve padding (=). Do not strip it.
3.4: Import to WorkOS
Use User Management API with the formatted hash:
POST /user_management/users
{
"email": "user@example.com",
"password_hash": "$firebase-scrypt$ln=8,r=14$sk=abc123==$ss=xyz789==$user_salt$user_hash"
}
Or update existing user:
PUT /user_management/users/:id
{
"password_hash": "$firebase-scrypt$ln=8,r=14$sk=abc123==$ss=xyz789==$user_salt$user_hash"
}
Check the fetched docs for exact endpoint paths — they may use different naming (e.g., /reference/authkit/user/create).
Step 4: Social Provider Migration
4.1: Export Firebase OAuth Credentials
From Firebase Console:
- Authentication > Sign-in method
- For each enabled provider (Google, Microsoft, GitHub, etc.):
- Note the Client ID
- Reveal and copy the Client Secret
4.2: Configure in WorkOS
Navigate to WorkOS Dashboard → Configuration → Authentication Methods.
For each provider:
- Enable the provider
- Enter the SAME Client ID from Firebase
- Enter the SAME Client Secret from Firebase
- Configure redirect URIs (must match your application's callback routes)
Supported providers:
- Google (https://workos.com/docs/integrations/google-oauth)
- Microsoft (https://workos.com/docs/integrations/microsoft-oauth)
- GitHub (check docs for availability)
If provider not listed: Email support@workos.com with provider name and use case.
4.3: Update Application Code
Replace Firebase OAuth calls with WorkOS AuthKit:
// Before (Firebase)
signInWithPopup(auth, new GoogleAuthProvider());
// After (WorkOS AuthKit)
// Use getAuthorizationUrl with provider hint
const authUrl = getAuthorizationUrl({
provider: 'GoogleOAuth',
redirectUri: 'https://yourapp.com/callback',
});
window.location.href = authUrl;
Check fetched docs for exact method names — syntax may differ by SDK.
Step 5: Magic Auth Migration (Email Link)
Firebase Email Link → WorkOS Magic Auth:
5.1: Remove Firebase Email Link Code
Delete calls to:
sendSignInLinkToEmail()isSignInWithEmailLink()signInWithEmailLink()
5.2: Implement WorkOS Magic Auth
Use Magic Auth API:
POST /user_management/magic_auth/send
{
"email": "user@example.com"
}
User flow:
- User enters email
- App calls Magic Auth API
- User clicks link in email
- Link redirects to your callback route
- Exchange code for session (standard AuthKit flow)
Check fetched docs for exact endpoint and parameter names.
Step 6: Enterprise Auth Migration (OIDC/SAML)
6.1: Export Firebase Enterprise Connections
From Firebase Console:
- Authentication > Sign-in method
- For each OIDC/SAML provider:
- Note the provider configuration (issuer URL, client ID, etc.)
- Export any custom claim mappings
6.2: Recreate in WorkOS
WorkOS supports the SAME identity providers:
OIDC: https://workos.com/docs/integrations/oidc
SAML: https://workos.com/docs/integrations/saml
Critical: WorkOS uses a per-organization connection model. If Firebase used a single global OIDC/SAML config for all users, you'll need to create a "default" organization in WorkOS and assign all migrated users to it.
6.3: Update Identity Provider Configuration
In your IdP (Okta, Azure AD, etc.):
- Update redirect URIs to WorkOS endpoints (shown in WorkOS Dashboard after connection creation)
- Update issuer/audience if changed
- Test SSO flow before migrating production users
Step 7: User Data Migration
7.1: Export User Profiles
firebase auth:export users.json --format=json
7.2: Map Firebase Fields to WorkOS
| Firebase Field | WorkOS Field | Notes |
|---|---|---|
localId |
N/A (new ID) | WorkOS generates new user IDs |
email |
email |
Required |
displayName |
first_name/last_name |
Split if needed |
photoUrl |
Custom metadata | Store in user metadata |
emailVerified |
email_verified |
Boolean flag |
disabled |
N/A | Handle separately (do not import disabled users) |
7.3: Import Users
Batch import script pattern:
const users = JSON.parse(fs.readFileSync('users.json'));
for (const user of users.users) {
if (user.disabled) continue; // Skip disabled accounts
const payload = {
email: user.email,
email_verified: user.emailVerified || false,
first_name: user.displayName?.split(' ')[0],
last_name: user.displayName?.split(' ').slice(1).join(' '),
};
// Add password hash if exists (see Step 3.3)
if (user.passwordHash) {
payload.password_hash = formatFirebaseScryptHash(user);
}
await workos.userManagement.createUser(payload);
}
Check fetched docs for exact SDK method names.
Step 8: Application Code Migration
8.1: Replace Firebase SDK Imports
// Remove Firebase
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth';
// Add WorkOS AuthKit
import { WorkOS } from '@workos-inc/node'; // or appropriate SDK
8.2: Authentication Flow Changes
Before (Firebase):
const userCredential = await signInWithEmailAndPassword(auth, email, password);
const token = await userCredential.user.getIdToken();
After (WorkOS):
// Redirect to WorkOS auth
const authUrl = workos.userManagement.getAuthorizationUrl({
provider: 'authkit',
redirectUri: 'https://yourapp.com/callback',
});
// Handle callback
const { user } = await workos.userManagement.authenticateWithCode({
code: req.query.code,
clientId: process.env.WORKOS_CLIENT_ID,
});
Check fetched docs for exact patterns — they may use different method names or flows.
8.3: Session Management Changes
Firebase uses client-side sessions via onAuthStateChanged().
WorkOS uses server-side sessions via encrypted cookies (AuthKit SDK).
If migrating a Next.js app from Firebase, follow the workos-authkit-nextjs skill for session handling patterns.
Verification Checklist (ALL MUST PASS)
# 1. Check password hash format (sample)
echo "$firebase-scrypt$ln=8,r=14$sk=test$ss=test$salt$hash" | grep -E '^\$firebase-scrypt\$ln=[0-9]+,r=[0-9]+\$sk=.+\$ss=.+\$.+\$.+$'
# 2. Verify WorkOS user creation endpoint responds
curl -X POST https://api.workos.com/user_management/users \
-H "Authorization: Bearer $WORKOS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com"}' \
| jq -e '.id'
# 3. Check social provider config exists in Dashboard
# (Manual: verify via WorkOS Dashboard UI)
# 4. Verify app builds without Firebase SDK
npm run build 2>&1 | grep -i firebase && echo "FAIL: Firebase still referenced"
# 5. Test auth flow end-to-end
# (Manual: sign in with migrated credentials)
Error Recovery
"Invalid password hash format"
Root cause: PHC string malformed or missing parameters.
Fix:
- Verify rounds, memCost, signerKey, saltSeparator are all present
- Check base64 padding preserved (= signs)
- Validate format:
$firebase-scrypt$ln=X,r=Y$sk=Z$ss=W$salt$hash - Use a test hash to verify API accepts format before batch import
"User already exists"
Root cause: Email collision during import.
Fix:
- Check if user already imported (query by email)
- If duplicate, skip or update with
PUT /users/:id - For batch imports, implement idempotency check before create
"OAuth redirect URI mismatch"
Root cause: WorkOS callback URL doesn't match registered redirect URIs.
Fix:
- WorkOS Dashboard → Configuration → Redirect URIs
- Add your callback URL (e.g.,
https://yourapp.com/auth/callback) - Verify protocol (https vs http), subdomain, and path match exactly
"Provider not configured"
Root cause: Social auth provider not enabled in WorkOS Dashboard.
Fix:
- Dashboard → Authentication Methods
- Enable the provider (Google, Microsoft, etc.)
- Enter Client ID and Client Secret from Firebase Console
- Save and retry
"SAML/OIDC connection not working after migration"
Root cause: Identity provider still pointing to Firebase URLs.
Fix:
- Get WorkOS SSO URLs from Dashboard (shown after creating connection)
- Update IdP configuration:
- ACS URL / Redirect URI → WorkOS callback URL
- Entity ID / Audience → WorkOS value
- Test SSO flow with a test user before migrating production
"Session not persisting after login"
Root cause: Missing AuthKit session middleware or cookies not configured.
Fix:
- Check middleware.ts or proxy.ts exists (see workos-authkit-nextjs skill)
- Verify
WORKOS_COOKIE_PASSWORDis set (32+ characters) - Ensure callback route properly handles session creation
- For Next.js 15+, verify async/await on cookie operations
Related Skills
- workos-authkit-nextjs - If migrating a Next.js + Firebase app
- workos-authkit-react - If migrating a React SPA with Firebase
- workos-magic-link - Deep dive on Magic Auth (Email Link replacement)
- workos-api-sso - Enterprise SSO migration (OIDC/SAML)
- workos-api-authkit - User Management API reference