A React Native mobile app for tracking recreational tennis matches with statistics and insights.
# Install Node.js (16+ required)
# Install Expo CLI
npm install -g expo-cli
firebaseConfig.jsconst firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
projectId: "YOUR_PROJECT_ID",
// ... other values
};
npm install
# Start Expo development server
npm start
# Or run directly on iOS
npm run ios
# Or run directly on Android
npm run android
In TennisTrackerApp.jsx, uncomment the Firebase imports and integrate the authentication and database functions:
Authentication:
import { auth } from './firebaseConfig';
import { createUserWithEmailAndPassword, signInWithEmailAndPassword } from 'firebase/auth';
// In handleAuth function:
if (isRegister) {
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
setUser(userCredential.user);
} else {
const userCredential = await signInWithEmailAndPassword(auth, email, password);
setUser(userCredential.user);
}
Firestore:
import { db } from './firebaseConfig';
import { collection, addDoc, query, where, getDocs, orderBy } from 'firebase/firestore';
// In addMatch function:
await addDoc(collection(db, 'matches'), {
userId: user.uid,
opponent: opponentName,
myScore,
opponentScore,
courtType,
result,
date: matchDate,
createdAt: new Date()
});
// In loadMatches function:
const q = query(
collection(db, 'matches'),
where('userId', '==', user.uid),
orderBy('date', 'desc')
);
const querySnapshot = await getDocs(q);
const matchesData = querySnapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
setMatches(matchesData);
matches (collection)
└── matchId (document)
├── userId: string
├── opponent: string
├── myScore: string
├── opponentScore: string
├── courtType: string (hard/clay/grass/indoor)
├── result: string (win/loss)
├── date: string (YYYY-MM-DD)
└── createdAt: timestamp
Add these rules in Firebase Console > Firestore Database > Rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /matches/{matchId} {
allow read, write: if request.auth != null &&
request.auth.uid == resource.data.userId;
allow create: if request.auth != null;
}
}
}
npm start# Build for iOS
expo build:ios
# Build for Android
expo build:android
MIT