This guide will walk you through setting up Firebase authentication and database, as well as integrating Google's Gemini AI API for the Allen THSBA Fishing Team app.
- Go to the Firebase Console
- Click "Create a project" or "Add project"
- Enter project name:
allen-thsba-fishing-team - Enable Google Analytics (recommended)
- Choose or create a Google Analytics account
- Click "Create project"
- In the Firebase Console, navigate to Authentication > Sign-in method
- Enable the following sign-in providers:
- Email/Password: Click "Enable" and save
- Google (optional): Click "Enable", add your domain, and save
- Go to Authentication > Users to manage users later
- Navigate to Firestore Database in the Firebase Console
- Click "Create database"
- Choose "Start in test mode" (we'll secure it later)
- Select a location closest to your users (e.g.,
us-central1) - Click "Done"
Replace the default rules with these secure rules:
```javascript rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // Users can read/write their own user document match /users/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; }
// Tournament posts - authenticated users can read all, write their own
match /posts/{postId} {
allow read: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == resource.data.userId;
allow update, delete: if request.auth != null && request.auth.uid == resource.data.userId;
}
// Tournament data - read only for authenticated users
match /tournaments/{tournamentId} {
allow read: if request.auth != null;
allow write: if request.auth != null &&
get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role in ['coach', 'captain'];
}
// Practice logs - users can manage their own
match /practiceLogs/{logId} {
allow read, write: if request.auth != null && request.auth.uid == resource.data.userId;
}
} } ```
- Go to Project Settings (gear icon) > General
- Scroll down to "Your apps" section
- Click "Add app" and select the web icon (
</>) - Register your app with nickname:
allen-thsba-web - Copy the Firebase configuration object
- Go to Google AI Studio
- Sign in with your Google account
- Click "Get API key" in the top right
- Create a new API key or use an existing one
- Copy the API key (keep it secure!)
- Go to Google Cloud Console
- Select your project or create a new one
- Enable billing for the project
- Navigate to APIs & Services > Library
- Search for "Generative Language API" and enable it
Create a .env.local file in your project root with the following variables:
```bash
NEXT_PUBLIC_FIREBASE_API_KEY=your_firebase_api_key NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_project_id.firebaseapp.com NEXT_PUBLIC_FIREBASE_PROJECT_ID=your_project_id NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_project_id.appspot.com NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_sender_id NEXT_PUBLIC_FIREBASE_APP_ID=your_app_id
GEMINI_API_KEY=your_gemini_api_key
NEXT_PUBLIC_DEV_URL=http://localhost:3000 ```
```bash npm install firebase @google/generative-ai ```
Create lib/firebase.ts:
```typescript import { initializeApp } from 'firebase/app' import { getAuth } from 'firebase/auth' import { getFirestore } from 'firebase/firestore'
const firebaseConfig = { apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, }
const app = initializeApp(firebaseConfig) export const auth = getAuth(app) export const db = getFirestore(app) ```
Create hooks/useFirebaseAuth.ts:
```typescript import { useState, useEffect } from 'react' import { User, onAuthStateChanged, signInWithEmailAndPassword, createUserWithEmailAndPassword, signOut } from 'firebase/auth' import { auth } from '@/lib/firebase'
export function useFirebaseAuth() { const [user, setUser] = useState<User | null>(null) const [loading, setLoading] = useState(true)
useEffect(() => { const unsubscribe = onAuthStateChanged(auth, (user) => { setUser(user) setLoading(false) })
return unsubscribe
}, [])
const signIn = async (email: string, password: string) => { return signInWithEmailAndPassword(auth, email, password) }
const signUp = async (email: string, password: string) => { return createUserWithEmailAndPassword(auth, email, password) }
const logout = async () => { return signOut(auth) }
return { user, loading, signIn, signUp, logout, } } ```
Create lib/gemini.ts:
```typescript import { GoogleGenerativeAI } from '@google/generative-ai'
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!)
export async function generateFishingAdvice(prompt: string) { try { const model = genAI.getGenerativeModel({ model: 'gemini-pro' })
const fishingContext = `You are an expert bass fishing guide with extensive knowledge of North Texas lakes including Ray Roberts, Lewisville, Tawakoni, and Cedar Creek. Provide helpful, specific advice for high school bass fishing tournament competitors.`
const result = await model.generateContent(`${fishingContext}\n\nQuestion: ${prompt}`)
const response = await result.response
return response.text()
} catch (error) { console.error('Error generating fishing advice:', error) throw new Error('Failed to generate fishing advice') } }
export async function generateTournamentStrategy(lake: string, date: string, conditions?: string) { try { const model = genAI.getGenerativeModel({ model: 'gemini-pro' })
const prompt = `Generate a tournament fishing strategy for ${lake} on ${date}. ${conditions ? `Current conditions: ${conditions}` : ''} Focus on techniques, lures, and locations that would be effective for high school tournament bass fishing.`
const result = await model.generateContent(prompt)
const response = await result.response
return response.text()
} catch (error) { console.error('Error generating tournament strategy:', error) throw new Error('Failed to generate tournament strategy') } } ```
Create lib/firestore.ts:
```typescript import { collection, addDoc, getDocs, query, where, orderBy, Timestamp } from 'firebase/firestore' import { db } from './firebase'
export interface FirestorePost { id?: string userId: string userName: string content: string type: 'note' | 'catch' | 'gear-reminder' | 'tournament-update' tournamentId?: string timestamp: Timestamp likes: number catchDetails?: { species: string weight: number length: number lure: string location: string } }
export async function createPost(post: Omit<FirestorePost, 'id' | 'timestamp' | 'likes'>) { try { const docRef = await addDoc(collection(db, 'posts'), { ...post, timestamp: Timestamp.now(), likes: 0, }) return docRef.id } catch (error) { console.error('Error creating post:', error) throw error } }
export async function getPosts(tournamentId?: string) { try { let q = query(collection(db, 'posts'), orderBy('timestamp', 'desc'))
if (tournamentId) {
q = query(collection(db, 'posts'), where('tournamentId', '==', tournamentId), orderBy('timestamp', 'desc'))
}
const querySnapshot = await getDocs(q)
return querySnapshot.docs.map(doc => ({
id: doc.id,
...doc.data(),
})) as FirestorePost[]
} catch (error) { console.error('Error getting posts:', error) throw error } } ```
- Start your development server:
npm run dev - Navigate to the login page
- Try creating a new account
- Check the Firebase Console > Authentication > Users to see the new user
- Create a test post in your app
- Check Firebase Console > Firestore Database to see the new document
- Verify security rules by trying to access data without authentication
Create a test API route pages/api/test-gemini.ts:
```typescript import { NextApiRequest, NextApiResponse } from 'next' import { generateFishingAdvice } from '@/lib/gemini'
export default async function handler(req: NextApiRequest, res: NextApiResponse) { if (req.method !== 'POST') { return res.status(405).json({ message: 'Method not allowed' }) }
try { const { prompt } = req.body const advice = await generateFishingAdvice(prompt) res.status(200).json({ advice }) } catch (error) { res.status(500).json({ error: 'Failed to generate advice' }) } } ```
Test by sending a POST request to /api/test-gemini with a fishing question.
- Never commit API keys to version control
- Use environment variables for all sensitive data
- Implement proper Firestore security rules
- Validate all user inputs before sending to APIs
- Set up Firebase App Check for production
- Monitor API usage to prevent abuse
- Use HTTPS in production
- Add environment variables in Vercel dashboard
- Update Firebase authorized domains to include your Vercel domain
- Update CORS settings if needed
- Install Firebase CLI:
npm install -g firebase-tools - Run
firebase init hosting - Build your app:
npm run build - Deploy:
firebase deploy
- "Firebase not initialized": Check environment variables
- "Permission denied": Review Firestore security rules
- "API key invalid": Verify Gemini API key and billing
- CORS errors: Add your domain to Firebase authorized domains
- Check browser console for errors
- Verify environment variables are loaded
- Test API endpoints individually
- Check Firebase Console logs
- Monitor network requests in browser dev tools
For team-specific issues, contact the development team or create an issue in the project repository.