@api-buddy/firebase
v2.0.0
Published
Firebase integration for API Buddy
Downloads
22
Maintainers
Readme
@api-buddy/firebase
Firebase integration for API Buddy. This package provides a set of utilities, type-safe operations, and React hooks for working with Firebase services in your API Buddy projects.
Features
- 🔒 Type-safe Firestore operations
- ⚡ Real-time data subscriptions
- 🎣 React hooks for easy integration
- 🔄 Optimistic updates
- 🔐 Security rules templates
- 🚀 Batch and transaction support
Installation
pnpm add @api-buddy/firebase firebaseQuick Start
Initialize Firebase
// lib/firebase.ts
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
import { getAuth } from 'firebase/auth';
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,
// ... other config
};
const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
export const auth = getAuth(app);Firestore Operations
Basic CRUD Operations
import { FirestoreService } from '@api-buddy/firebase';
interface User {
name: string;
email: string;
createdAt: Date;
}
const usersService = new FirestoreService<User>('users');
// Create
export const createUser = async (id: string, userData: User) => {
return usersService.create(id, userData);
};
// Read
export const getUser = async (id: string) => {
return usersService.get(id);
};
// Update
export const updateUser = async (id: string, updates: Partial<User>) => {
return usersService.update(id, updates);
};
// Delete
export const deleteUser = async (id: string) => {
return usersService.delete(id);
};Querying Data
// Get all active users, ordered by name
const activeUsers = await usersService.query({
where: [['status', '==', 'active']],
orderBy: [['name', 'asc']],
limit: 10
});
// Pagination
const firstPage = await usersService.query({
orderBy: [['createdAt', 'desc']],
limit: 10
});
const nextPage = await usersService.query({
orderBy: [['createdAt', 'desc']],
startAfter: firstPage[firstPage.length - 1],
limit: 10
});React Hooks
useDocument Hook
import { useDocument } from '@api-buddy/firebase';
function UserProfile({ userId }: { userId: string }) {
const usersService = useFirestoreService<User>('users');
const { data: user, loading, error } = useDocument(usersService, userId);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
if (!user) return <div>User not found</div>;
return (
<div>
<h1>{user.name}</h1>
<p>Email: {user.email}</p>
</div>
);
}useCollection Hook
import { useCollection } from '@api-buddy/firebase';
function UserList() {
const usersService = useFirestoreService<User>('users');
const {
data: users,
loading,
error,
hasMore,
fetchMore
} = useCollection(usersService, {
where: [['status', '==', 'active']],
orderBy: [['createdAt', 'desc']],
limit: 10
});
if (loading && !users?.length) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
{users.map(user => (
<UserCard key={user.id} user={user} />
))}
{hasMore && (
<button onClick={fetchMore} disabled={loading}>
{loading ? 'Loading...' : 'Load More'}
</button>
)}
</div>
);
}useRealtimeCollection Hook
import { useRealtimeCollection } from '@api-buddy/firebase';
function RealtimeComments({ postId }: { postId: string }) {
const commentsService = useFirestoreService<Comment>('comments');
const { data: comments, loading, error } = useRealtimeCollection(commentsService, {
where: [['postId', '==', postId]],
orderBy: [['createdAt', 'asc']]
});
if (loading) return <div>Loading comments...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
{comments.map(comment => (
<CommentItem key={comment.id} comment={comment} />
))}
</div>
);
}Security Rules
We provide a set of recommended security rules in the security-rules directory. To deploy them:
- Copy the rules to your Firebase project
- Run the deployment script:
# Set your Firebase project ID
FIREBASE_PROJECT=your-project-id pnpm tsx scripts/deploy-rules.tsEnvironment Variables
# Firebase Config
NEXT_PUBLIC_FIREBASE_API_KEY=your-api-key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-project.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your-messaging-sender-id
NEXT_PUBLIC_FIREBASE_APP_ID=your-app-id
NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=G-XXXXXXXXXX
# For local development
FIREBASE_EMULATOR_HOST=localhost
FIREBASE_FIRESTORE_EMULATOR_PORT=8080
FIREBASE_AUTH_EMULATOR_PORT=9099TypeScript Support
All Firestore operations are fully typed. Define your data models as TypeScript interfaces:
interface Product {
name: string;
price: number;
category: string;
createdAt: Date;
updatedAt: Date;
}
const productsService = new FirestoreService<Product>('products');
// All operations will be type-checked against the Product interfaceError Handling
All operations throw standard Firebase errors. You can catch and handle them appropriately:
try {
await usersService.update('user123', { name: 'New Name' });
} catch (error) {
if (error.code === 'permission-denied') {
console.error('You do not have permission to update this user');
} else {
console.error('Error updating user:', error);
}
}License
MIT
