Skip to main content

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

1

Create Firebase Project

  1. Go to Firebase Console
  2. Click Add Project
  3. Enter your project name (e.g., “educastream”)
  4. Follow the setup wizard
2

Enable Firebase Storage

  1. In your Firebase project, navigate to BuildStorage
  2. Click Get Started
  3. Choose security rules (start in test mode for development)
  4. Select a Cloud Storage location
  5. Click Done
3

Register Web App

  1. In Project Settings, scroll to Your apps
  2. Click the Web icon (</>)
  3. Register your app with a nickname
  4. You’ll receive your Firebase configuration object
4

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:
.env
# 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:
firebase.js
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!

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

1

Check Storage Usage

In Firebase Console, go to Storage to view:
  • Total storage used
  • Number of files
  • Download bandwidth
2

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);
Storage instance exists
Bucket name is correct
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

Build docs developers (and LLMs) love