OAuth2 Setup Guide - Phase 1 Implementation¶
Status: Ready for Configuration
Date: December 28, 2025
Version: 1.0
๐ Overview¶
This guide walks through enabling multiple OAuth2 providers in Firebase Console and testing them with the updated Gavekort multi-tenant app.
Supported Providers: - โ Google Sign-In (Recommended - already configured) - โ GitHub OAuth - โ Apple Sign In (requires Apple Developer account) - โ Email/Password (fallback option)
๐ง Step 1: Enable OAuth Providers in Firebase Console¶
A. Google Sign-In (Already Enabled)¶
- Go to: https://console.firebase.google.com/project/gavekort-multitenant/authentication/providers
- Verify "Google" is enabled (should be โ )
- Configure if needed:
- Web Client ID: (shown in Firebase Console)
- Support email: Provide your contact email
B. Enable GitHub OAuth¶
- Firebase Console Setup:
- Navigate to: Authentication โ Sign-in method โ GitHub
-
Click "Enable"
-
GitHub App Setup (OAuth App):
- Go to: https://github.com/settings/developers
- Click "OAuth Apps" โ "New OAuth App"
- Fill in:
- Application name:
Gavekort Multi-Tenant - Homepage URL:
https://gavekort-multitenant.web.app - Authorization callback URL:
https://gavekort-multitenant.firebaseapp.com/__/auth/handler
- Application name:
-
Copy the generated:
- Client ID
- Client Secret
-
Back to Firebase Console:
- Paste Client ID and Client Secret in the GitHub provider settings
- Click "Save"
C. Enable Apple Sign In (Optional)¶
- Firebase Console Setup:
- Navigate to: Authentication โ Sign-in method โ Apple
-
Click "Enable"
-
Apple Developer Setup (requires Apple Developer account):
- Go to: https://developer.apple.com/account/resources/identifiers/list
- Create a new "Service ID" for
Sign in with Apple - Configure with your domain
-
Generate a private key and download it
-
Back to Firebase Console:
- Configure Apple provider with:
- Team ID: (from Apple Developer)
- Key ID: (from private key)
- Private Key: (from downloaded .p8 file)
- Click "Save"
๐ Step 2: Update Your App Configuration¶
Environment Variables (.env.local)¶
The following are already configured in webapp/.env.local:
REACT_APP_FIREBASE_API_KEY=AIzaSyCG2CaNMx6Z7P8jC28mu_ZwuPXEvImeBjM
REACT_APP_FIREBASE_AUTH_DOMAIN=gavekort-multitenant.firebaseapp.com
REACT_APP_FIREBASE_PROJECT_ID=gavekort-multitenant
REACT_APP_FIREBASE_STORAGE_BUCKET=gavekort-multitenant.firebasestorage.app
REACT_APP_FIREBASE_MESSAGING_SENDER_ID=380848678496
REACT_APP_FIREBASE_APP_ID=1:380848678496:web:2d09563be3465b0b208505
REACT_APP_API_BASE_URL=https://europe-west1-gavekort-multitenant.cloudfunctions.net
No additional configuration needed - the app automatically detects enabled providers.
๐ฆ Step 3: Deploy Cloud Functions¶
The OAuth2 Cloud Functions are now ready to deploy:
cd functions
npm run build
firebase deploy --only functions
New Functions Deployed:
- onAuthCreate - Triggered automatically on user creation (triggers custom claims)
- log_signin_event - Log sign-in events for security audit
- link_oauth_provider - Allow users to link multiple providers
- get_oauth_providers - Get user's linked providers
๐งช Step 4: Test OAuth2 Authentication¶
Test in Development¶
# Terminal 1: Start Firebase Emulator
firebase emulators:start
# Terminal 2: Start React app
cd webapp
npm start
Visit: http://localhost:3000/
Test flows: 1. Click "Google" โ Should open Google login popup 2. Click "GitHub" โ Should open GitHub login popup 3. Click "Apple" โ Should open Apple login popup (if enabled) 4. Fill email/password โ Traditional sign-up/login
Expected Behavior¶
After successful OAuth login:
1. โ
User is created in Firebase Auth
2. โ
Custom claims set automatically (role: "END_USER")
3. โ
User document created in Firestore
4. โ
Auth history recorded
5. โ
User redirected to /wallet
๐ Step 5: Security & Best Practices¶
Firestore Security Rules (Already Configured)¶
The following rules are in firestore.rules:
match /users/{userId} {
allow read: if request.auth.uid == userId;
allow write: if request.auth.uid == userId;
allow read, write: if request.auth.token.role == 'ADMIN';
}
- โ Users can only read/write their own documents
- โ Admin users can access all user documents
Custom Claims (Set Automatically)¶
When a user signs up via OAuth:
{
"role": "END_USER",
"createdAt": "2025-12-28T...",
"provider": "google.com",
"providerEmail": "user@example.com"
}
Roles Available:
- END_USER - Normal club member (default)
- ADMIN - Club manager/staff (set manually)
- CLUB - System administrator (set manually)
๐ฑ Step 6: Mobile/Cross-Tab Handling¶
Redirect-Based Flow (for mobile)¶
The app now handles redirect-based OAuth for: - Mobile browsers that block popups - Cross-tab sign-in flows
Implementation: LoginPage.tsx calls handleRedirectResult() on mount.
๐ Troubleshooting¶
Issue: "Popup blocked" error¶
Solution: - Ensure popups are allowed in browser settings - Test in incognito/private mode
Issue: "Account exists with different credential"¶
Solution: - User already has account with different provider - Can link providers from user settings (not yet implemented)
Issue: Custom claims not set¶
Solution:
1. Check Cloud Functions deployed: firebase deploy --only functions
2. Check function logs: firebase functions:log
3. Wait 60 seconds after user creation (async operation)
Issue: Users not appearing in Firestore¶
Solution:
1. Check users collection exists in Firestore
2. Check function permissions: gcloud projects add-iam-policy-binding PROJECT_ID --member=serviceAccount:ACCOUNT --role=roles/datastore.user
๐ Monitoring & Logging¶
View OAuth Sign-Ins¶
# View all authentication history
firebase functions:log --only onAuthCreate,log_signin_event
Monitor in Firebase Console¶
- Go to: https://console.firebase.google.com/project/gavekort-multitenant/functions
- Click function โ "Logs"
- Filter by date/provider
View User Documents¶
- Firebase Console โ Firestore Database
- Collection:
users - Each user document contains:
emailauthProvider(google.com, github.com, apple.com)authProvidersLinked(array of linked providers)role(END_USER, ADMIN, CLUB)createdAttimestamplastSignIntimestamp
๐ Linking Multiple Providers (Future)¶
Users can link multiple OAuth providers once "Account Settings" is implemented:
// Future implementation in AccountSettings component
const linkGitHub = async () => {
const result = await linkOAuthProvider({ provider: "github.com" });
// Success: User can now sign in with GitHub
};
โ Deployment Checklist¶
Before deploying to production:
- [ ] All OAuth providers enabled in Firebase Console
- [ ] GitHub OAuth App created and credentials added
- [ ] Apple Sign In configured (if required)
- [ ] Cloud Functions deployed:
firebase deploy --only functions - [ ] Firestore security rules updated:
firebase deploy --only firestore:rules - [ ] Environment variables configured
- [ ] Test all auth flows in staging
- [ ] Monitor logs for errors
- [ ] Create user documentation for sign-in methods
๐ Related Files¶
- LoginPage.tsx - Multi-provider login UI
- oauthAuth.ts - OAuth service layer
- oauth.ts - Cloud Functions implementation
- Auth.css - Login page styling
- EXTENDED_DEVELOPMENT_PLAN.md - Full platform roadmap
๐ Next Steps (Phase 2)¶
After OAuth2 is stable:
- Wallet Items List - Show all claimed giftcards
- Transaction Filters - Filter by date/type
- CSV Export - Download transaction history
- Account Settings - Link/unlink providers
See FEATURES_ROADMAP.md for Phase 2+ details.
Questions? Check Firebase docs: - Firebase Auth Providers - GitHub OAuth Integration - Apple Sign In