Pattern: All services use the singleton pattern and export a single instance. Import using import serviceName from '@/src/services/serviceName'
Authentication Services
Firebase authentication operations
authService
Handles all authentication operations including email/password and Google Sign-In. Automatically sends verification emails on signup.
Methods
signUp(email: string, password: string, displayName: string): Promise<User>
signIn(email: string, password: string): Promise<User>
signInWithGoogle(): Promise<User>
sendVerificationEmail(): Promise<void>
resetPassword(email: string): Promise<void>
signOut(): Promise<void>
getCurrentUser(): User | null
deleteAccount(): Promise<void>
Usage Example
import authService from '@/src/services/authService';
// Sign up new user
const user = await authService.signUp(
'student@college.edu',
'password123',
'John Doe'
);
// Sign in existing user
const user = await authService.signIn(email, password);
// Google Sign-In
const user = await authService.signInWithGoogle();
// Password reset
await authService.resetPassword('student@college.edu');
Data Services
Firestore database operations
firestoreService
Core database service for user profiles, timetables, and attendance tracking.
User Profile Methods
createUserProfile(uid: string, data: UserProfile): Promise<void>
getUserProfile(uid: string): Promise<UserProfile | null>
updateUserProfile(uid: string, data: Partial<UserProfile>): Promise<void>
deleteUserProfile(uid: string): Promise<void>
Timetable Methods (Manual Entry CRUD)
These methods support the manual timetable entry feature where users add/edit/delete entries one by one:
saveTimetable(uid: string, entries: TimetableEntry[]): Promise<void>
getTimetable(uid: string): Promise<TimetableEntry[]>
addTimetableEntry(uid: string, entry: TimetableEntry): Promise<string>
updateTimetableEntry(uid: string, entryId: string, data: Partial<TimetableEntry>): Promise<void>
deleteTimetableEntry(uid: string, entryId: string): Promise<void>
Subjects & Attendance Methods
getSubjects(uid: string): Promise<Subject[]>
addSubject(uid: string, subject: Subject): Promise<string>
updateSubject(uid: string, subjectId: string, data: Partial<Subject>): Promise<void>
deleteSubject(uid: string, subjectId: string): Promise<void>
updateSubjectAttendance(uid: string, subjectId: string, attended: number, total: number): Promise<void>
markAttendance(uid: string, subjectId: string, present: boolean): Promise<void>
notesService
Notes creation, editing, and feed generation for the collaborative notes feature.
CRUD Methods
createNote(authorId: string, data: CreateNoteInput): Promise<Note>
updateNote(noteId: string, data: Partial<Note>): Promise<void>
deleteNote(noteId: string, authorId: string): Promise<void>
getNoteById(noteId: string): Promise<Note | null>
getNoteWithContext(noteId: string, userId: string): Promise<FeedNote>
Feed & Discovery Methods
getFeedNotes(userId: string, followingIds: string[], lastDoc?: any): Promise<PaginatedResult<FeedNote>>
getExploreNotes(userId: string, filters?: NoteFilters, lastDoc?: any): Promise<PaginatedResult<FeedNote>>
getUserNotes(authorId: string, viewerId: string, lastDoc?: any): Promise<PaginatedResult<FeedNote>>
searchNotes(userId: string, query: string, filters?: NoteFilters): Promise<FeedNote[]>
Usage Example
import notesService from '@/src/services/notesService';
// Create a new note
const note = await notesService.createNote(userId, {
title: 'Physics Chapter 5 Notes',
description: 'Complete notes on thermodynamics',
contentType: 'text',
content: '# Thermodynamics...',
subject: 'Physics',
tags: ['physics', 'thermodynamics'],
isPublic: true
});
// Get feed (notes from followed users)
const feed = await notesService.getFeedNotes(userId, followingIds);
console.log(feed.items, feed.hasMore);
groupsService
Study groups with real-time messaging, member management, and notifications.
Group Operations
createGroup(name, description, category, isPrivate, userId, userName, photoURL?, college?, course?, department?): Promise<string>
getGroup(groupId: string): Promise<Group | null>
getPublicGroups(limit?: number): Promise<Group[]>
getUserGroups(userId: string): Promise<Group[]>
updateGroup(groupId: string, updates: Partial<Group>): Promise<void>
deleteGroup(groupId: string): Promise<void>
Member Operations
joinGroup(groupId, userId, userName, photoURL?): Promise<void>
leaveGroup(groupId: string, userId: string): Promise<void>
addMember(groupId, userId, userName, photoURL?, role?): Promise<void>
removeMember(groupId: string, userId: string): Promise<void>
updateMemberRole(groupId, userId, newRole): Promise<void>
getGroupMembers(groupId: string): Promise<GroupMember[]>
isMember(groupId: string, userId: string): Promise<boolean>
Messaging Operations
sendMessage(groupId, userId, userName, photoURL?, message, fileUrl?, fileName?, fileType?): Promise<string>
getMessages(groupId: string, limit?: number): Promise<GroupMessage[]>
subscribeToMessages(groupId, callback, limit?): Unsubscribe
deleteMessage(groupId: string, messageId: string): Promise<void>
editMessage(groupId, messageId, newMessage): Promise<void>
Real-time Subscriptions
subscribeToMyGroups(userId: string, callback: (groups: Group[]) => void): Unsubscribe
Usage Example
import groupsService from '@/src/services/groupsService';
// Create a study group
const groupId = await groupsService.createGroup(
'Physics Study Group',
'Preparing for finals',
'study',
false, // public
userId,
'John Doe'
);
// Subscribe to real-time messages
const unsubscribe = groupsService.subscribeToMessages(
groupId,
(messages) => {
console.log('New messages:', messages);
}
);
// Send a message
await groupsService.sendMessage(
groupId,
userId,
'John Doe',
photoURL,
'Hello everyone!'
);
// Cleanup
unsubscribe();
Social Services
Social interactions and following system
socialService
Handles likes, comments, saves, and download tracking for notes.
Like Operations
likeNote(noteId: string, userId: string): Promise<void>
unlikeNote(noteId: string, userId: string): Promise<void>
toggleLike(noteId: string, userId: string): Promise<boolean>
isNoteLiked(noteId: string, userId: string): Promise<boolean>
getNoteLikes(noteId: string): Promise<string[]>
Comment Operations
addComment(noteId: string, comment: Omit<NoteComment, 'id' | 'createdAt'>): Promise<NoteComment>
updateComment(noteId: string, commentId: string, content: string): Promise<void>
deleteComment(noteId: string, commentId: string): Promise<void>
getNoteComments(noteId: string): Promise<NoteComment[]>
Save Operations
saveNote(noteId: string, userId: string): Promise<void>
unsaveNote(noteId: string, userId: string): Promise<void>
toggleSave(noteId: string, userId: string): Promise<boolean>
isNoteSaved(noteId: string, userId: string): Promise<boolean>
getSavedNotes(userId: string, lastDoc?: any): Promise<PaginatedResult<Note>>
followService
User following system with suggestions.
Methods
followUser(followerId: string, followingId: string): Promise<void>
unfollowUser(followerId: string, followingId: string): Promise<void>
toggleFollow(followerId: string, followingId: string): Promise<boolean>
isFollowing(followerId: string, followingId: string): Promise<boolean>
getFollowing(userId: string): Promise<string[]>
getFollowers(userId: string): Promise<string[]>
getFollowingCount(userId: string): Promise<number>
getFollowersCount(userId: string): Promise<number>
getSuggestedUsers(userId: string, college: string, course: string): Promise<PublicUserProfile[]>
Usage Example
import followService from '@/src/services/followService';
// Follow a user
await followService.followUser(myUserId, targetUserId);
// Get suggestions from same college
const suggestions = await followService.getSuggestedUsers(
myUserId,
'MIT College',
'Computer Science'
);
// Check if following
const isFollowing = await followService.isFollowing(myUserId, targetUserId);
OCR & Timetable Extraction Services
Alternative to manual entry: Extract timetable from images using OCR and AI parsing
Two ways to set up timetable:
1. Manual Entry (Default): Use firestoreService methods above to add/edit/delete entries with UI
2. OCR Extraction (Optional): Upload image → OCR extracts text → AI parses to entries → Review in manual entry screen
ocrService
OCR (Optical Character Recognition) service using OCR.space API to extract text from images. Supports multiple image formats and both web and native platforms.
Configuration
| Setting | Value |
|---|---|
| API Provider | OCR.space |
| OCR Engine | Engine 2 (advanced) |
| Supported Formats | JPG, PNG, GIF, WebP, BMP, TIFF |
| Table Detection | Enabled |
| Auto Scale | Enabled |
Methods
extractTextFromImage(imageUri: string): Promise<OCRResult>
OCRResult Interface
interface OCRResult {
success: boolean;
text: string;
error?: string;
}
Supported Input Types
| Input Type | Example | Platform |
|---|---|---|
| Base64 Data URI | data:image/png;base64,... | Web & Native |
| File URI | file:///path/to/image.jpg | Native only |
| Content URI | content://... | Android only |
| HTTP URL | https://example.com/image.png | Web & Native |
Usage Example
import { extractTextFromImage } from '@/src/services/ocrService';
// Extract text from image
const result = await extractTextFromImage('file:///path/to/timetable.jpg');
if (result.success) {
console.log('Extracted text:', result.text);
} else {
console.error('OCR failed:', result.error);
}
timetableParserService
AI-powered service that parses OCR-extracted text into structured TimetableEntry objects using Groq API (Llama 4 Maverick model).
Configuration
| Setting | Value |
|---|---|
| Model | meta-llama/llama-4-maverick-17b-128e-instruct |
| Temperature | 0.1 (low for structured output) |
| Max Tokens | 4096 |
| API | Groq Cloud API |
Methods
parseTimetableFromText(ocrText: string): Promise<ParseResult>
ParseResult Interface
interface ParseResult {
success: boolean;
entries: TimetableEntry[];
error?: string;
}
interface TimetableEntry {
id: string;
day: string; // Monday, Tuesday, etc.
subject: string; // Subject name
subjectCode?: string; // Subject code (if detected)
startTime: string; // HH:MM format
endTime: string; // HH:MM format
type?: string; // lecture, lab, tutorial
faculty?: string; // Teacher name (if detected)
room?: string; // Room/Location (if detected)
}
Usage Example
import { extractTextFromImage } from '@/src/services/ocrService';
import { parseTimetableFromText } from '@/src/services/timetableParserService';
// Step 1: Extract text from image
const ocrResult = await extractTextFromImage(imageUri);
if (ocrResult.success) {
// Step 2: Parse extracted text into timetable entries
const parseResult = await parseTimetableFromText(ocrResult.text);
if (parseResult.success) {
console.log('Parsed entries:', parseResult.entries);
// entries can be used to populate timetable
}
}
AI Services
AI-powered chat and assistance
chatService
Groq API integration for BunkBot AI assistant with context-aware responses.
Configuration
| Setting | Value |
|---|---|
| Model | meta-llama/llama-4-maverick-17b-128e-instruct |
| Temperature | 0.7 |
| Max Tokens | 2048 |
| API | Groq Cloud API |
Methods
sendMessage(
message: string,
history: ChatMessage[],
attendanceContext: AttendanceContext | null,
imageBase64?: string
): Promise<string>
quickPrompts: Array<{ label: string; prompt: string }>
Attendance Context Interface
interface AttendanceContext {
subjects: Subject[];
timetable: TimetableEntry[];
minimumAttendance: number;
userName: string;
}
Usage Example
import { sendMessage, quickPrompts } from '@/src/services/chatService';
// Send message with attendance context
const response = await sendMessage(
'Can I bunk physics class tomorrow?',
chatHistory,
{
subjects: userSubjects,
timetable: userTimetable,
minimumAttendance: 75,
userName: 'John'
}
);
// Use with image
const response = await sendMessage(
'Please analyze this timetable image',
chatHistory,
attendanceContext,
base64ImageData
);
Infrastructure Services
Caching, offline support, and notifications
cacheService
AsyncStorage-based local caching for offline access.
Methods
cacheUserProfile(uid: string, profile: UserProfile): Promise<void>
getCachedUserProfile(uid: string): Promise<UserProfile | null>
cacheSubjects(uid: string, subjects: Subject[]): Promise<void>
getCachedSubjects(uid: string): Promise<Subject[] | null>
cacheTimetable(uid: string, timetable: TimetableEntry[]): Promise<void>
getCachedTimetable(uid: string): Promise<TimetableEntry[] | null>
clearCache(uid: string): Promise<void>
clearAllCache(): Promise<void>
offlineQueueService
Queue-based offline operation handling with auto-sync.
Methods
queueOperation(operation: OfflineOperation): Promise<void>
processQueue(): Promise<void>
getQueueLength(): Promise<number>
clearQueue(): Promise<void>
Operation Types
type OfflineOperation = {
id: string;
type: 'create' | 'update' | 'delete';
collection: string;
documentId?: string;
data?: any;
timestamp: Date;
}
notificationService
Push notification registration and handling.
Methods
registerForPushNotificationsAsync(): Promise<string | null>
savePushToken(userId: string, token: string): Promise<void>
deletePushToken(userId: string): Promise<void>
setupNotificationListeners(): void
Note
Push notifications require a development build (EAS). They are not available in Expo Go for SDK 53+.
File Upload Services
Cloud storage integration
imageUploadService
Uploads images to Catbox.moe (CORS-friendly for avatars).
Methods
uploadImage(imageUri: string): Promise<string> // Returns URL
uploadImageBase64(base64: string, fileName: string): Promise<string>
googleDriveService
Google Drive API for note attachments (PDFs, images).
Methods
uploadFile(file: File): Promise<UploadResult>
deleteFile(fileId: string): Promise<void>
getFileUrl(fileId: string): string
getThumbnailUrl(fileId: string): string
Upload Result
interface UploadResult {
fileId: string;
fileName: string;
mimeType: string;
size: number;
webViewLink: string;
webContentLink: string;
thumbnailLink?: string;
}
chatStorageService
Persists chat conversations locally using AsyncStorage.
Methods
createChat(): Promise<Chat>
getAllChats(): Promise<Chat[]>
updateChatMessages(chatId: string, messages: ChatMessage[]): Promise<void>
deleteChat(chatId: string): Promise<void>
getActiveChatId(): Promise<string | null>
setActiveChatId(chatId: string): Promise<void>
Chat Interface
interface Chat {
id: string;
title: string;
messages: ChatMessage[];
createdAt: Date;
updatedAt: Date;
}
interface ChatMessage {
id: string;
role: 'user' | 'assistant';
content: string;
image?: string; // Base64
timestamp: Date;
}