Overview
EducaStream uses Firebase Storage to store and serve course-related media files including:
Course videos and lectures
Course thumbnail images
User profile pictures
Other course materials
Firebase Storage provides secure file uploads and downloads with built-in CDN distribution.
Firebase Setup
Create Firebase Project
Go to Firebase Console
Click Add Project
Enter your project name (e.g., “educastream”)
Follow the setup wizard
Enable Firebase Storage
In your Firebase project, navigate to Build → Storage
Click Get Started
Choose security rules (start in test mode for development)
Select a Cloud Storage location
Click Done
Register Web App
In Project Settings, scroll to Your apps
Click the Web icon (</>)
Register your app with a nickname
You’ll receive your Firebase configuration object
Copy Configuration
From the Firebase Console, copy your configuration values: {
apiKey : "AIzaSy..." ,
authDomain : "your-project.firebaseapp.com" ,
projectId : "your-project-id" ,
storageBucket : "your-project.appspot.com" ,
messagingSenderId : "123456789" ,
appId : "1:123456789:web:abc123"
}
Environment Variables
Add your Firebase configuration to the .env file:
# Firebase Configuration
VITE_API_KEY = AIzaSyXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
VITE_AUTH_DOMAIN = your-project.firebaseapp.com
VITE_PROJECT_ID = your-project-id
VITE_STORAGE_BUCKET = your-project.appspot.com
VITE_MESSAGING_SENDER_ID = 123456789012
VITE_APP_ID = 1:123456789012:web:abcdef123456
All environment variables for Vite must be prefixed with VITE_ to be accessible in the client-side code.
Firebase Implementation
The Firebase configuration is implemented in src/firebase/firebase.js:1-14:
import { initializeApp } from "firebase/app" ;
import { getStorage } from "firebase/storage" ;
const firebaseConfig = {
apiKey: import . meta . env . VITE_API_KEY ,
authDomain: import . meta . env . VITE_AUTH_DOMAIN ,
projectId: import . meta . env . VITE_PROJECT_ID ,
storageBucket: import . meta . env . VITE_STORAGE_BUCKET ,
messagingSenderId: import . meta . env . VITE_MESSAGING_SENDER_ID ,
appId: import . meta . env . VITE_APP_ID ,
};
export const appFireBase = initializeApp ( firebaseConfig );
export const storage = getStorage ( appFireBase );
Key Components
appFireBase Initialized Firebase app instance
storage Firebase Storage service for file operations
Using Firebase Storage
To upload or download files using Firebase Storage in your components:
Upload Files
import { ref , uploadBytes , getDownloadURL } from "firebase/storage" ;
import { storage } from "./firebase/firebase" ;
const uploadFile = async ( file ) => {
// Create a reference to the file location
const storageRef = ref ( storage , `courses/ ${ file . name } ` );
// Upload the file
const snapshot = await uploadBytes ( storageRef , file );
// Get the download URL
const downloadURL = await getDownloadURL ( snapshot . ref );
return downloadURL ;
};
Download URLs
import { ref , getDownloadURL } from "firebase/storage" ;
import { storage } from "./firebase/firebase" ;
const getFileURL = async ( filePath ) => {
const storageRef = ref ( storage , filePath );
const url = await getDownloadURL ( storageRef );
return url ;
};
Delete Files
import { ref , deleteObject } from "firebase/storage" ;
import { storage } from "./firebase/firebase" ;
const deleteFile = async ( filePath ) => {
const storageRef = ref ( storage , filePath );
await deleteObject ( storageRef );
};
Storage Security Rules
For production, configure proper security rules in Firebase Console:
Allow all reads and writes (testing only): rules_version = '2' ;
service firebase . storage {
match / b / { bucket } / o {
match / { allPaths =** } {
allow read , write : if true ;
}
}
}
This is insecure and should only be used during development!
Restrict based on authentication: rules_version = '2' ;
service firebase . storage {
match / b / { bucket } / o {
// Allow authenticated users to read all files
match / { allPaths =** } {
allow read : if request . auth != null ;
}
// Only instructors can upload courses
match / courses / { courseId } / { fileName } {
allow write : if request . auth != null
&& request . auth . token . role == 'instructor' ;
}
// Users can manage their own profile pictures
match / profiles / { userId } / { fileName } {
allow write : if request . auth != null
&& request . auth . uid == userId ;
}
}
}
Storage Organization
Organize your files in a structured manner:
storage-bucket/
├── courses/
│ ├── {courseId}/
│ │ ├── thumbnail.jpg
│ │ ├── video-1.mp4
│ │ ├── video-2.mp4
│ │ └── materials.pdf
├── profiles/
│ ├── {userId}/
│ │ └── avatar.jpg
└── lectures/
├── {lectureId}/
│ └── video.mp4
Best Practices
Use unique identifiers (courseId, userId) in file paths
Implement file size limits for uploads
Validate file types before uploading
Use loading states during uploads/downloads
Handle errors gracefully with user feedback
Compress images before uploading
Use appropriate MIME types
Error Handling
Always handle Firebase Storage errors:
import { ref , uploadBytes } from "firebase/storage" ;
import { storage } from "./firebase/firebase" ;
const uploadWithErrorHandling = async ( file ) => {
try {
const storageRef = ref ( storage , `courses/ ${ file . name } ` );
const snapshot = await uploadBytes ( storageRef , file );
const url = await getDownloadURL ( snapshot . ref );
return { success: true , url };
} catch ( error ) {
console . error ( "Upload failed:" , error );
// Handle specific error codes
if ( error . code === 'storage/unauthorized' ) {
return { success: false , error: 'Not authorized to upload' };
}
if ( error . code === 'storage/canceled' ) {
return { success: false , error: 'Upload canceled' };
}
if ( error . code === 'storage/quota-exceeded' ) {
return { success: false , error: 'Storage quota exceeded' };
}
return { success: false , error: 'Upload failed' };
}
};
Common Error Codes
User doesn’t have permission to access the object. Check your security rules.
User canceled the operation. This is normal for cancelled uploads.
Unknown error occurred. Check your internet connection and Firebase configuration.
Storage quota has been exceeded. Upgrade your Firebase plan or clean up old files.
File on client doesn’t match the checksum of the file received by server. Retry the upload.
Monitoring Usage
Check Storage Usage
In Firebase Console, go to Storage to view:
Total storage used
Number of files
Download bandwidth
Set Up Billing Alerts
Configure alerts for storage quota and bandwidth usage to avoid unexpected charges.
Testing
Verify your Firebase configuration:
import { storage } from "./firebase/firebase" ;
console . log ( "Firebase Storage initialized:" , storage );
console . log ( "Storage bucket:" , storage . app . options . storageBucket );
No console errors on initialization
Next Steps
Stripe Integration Configure payment processing
Architecture Understand the application structure
Additional Resources
Firebase Storage Docs Official Firebase Storage documentation