dvalin99 image

Firebase Storage: Your File Upload Superhero 📁

Overview

Hello everyone! 👋

In this article, I’ll walk you through Firebase Storage, Google’s powerful file storage solution that makes handling uploads, downloads, and file management incredibly easy. Whether you’re dealing with profile pictures, documents, videos, or any other files, Firebase Storage has got your back!

Firebase Storage is built on Google Cloud Storage, so you get enterprise-level reliability and performance without the complexity. Plus, it integrates seamlessly with Firebase Authentication and works beautifully across web, mobile, and server environments.

Let’s start! 🤙

Why Firebase Storage Rocks

Before we jump into the code, let’s understand what makes Firebase Storage so awesome:

Robust Upload/Download: Handles network interruptions gracefully with resumable uploads
Security: Built-in authentication and security rules
Scalability: Automatically scales from KB to petabytes
Global CDN: Fast downloads from Google’s global network
Real-time Integration: Works perfectly with Firestore and other Firebase services
Multiple Formats: Images, videos, documents, audio – you name it!

The best part? You don’t need to worry about server management, CDN configuration, or handling network failures.
Firebase does all the heavy lifting! 💪

Choose Your File Types

Firebase Storage can handle pretty much any file type you throw at it:

Images: JPG, PNG, GIF, WebP, SVG
Videos: MP4, MOV, AVI, WebM
Documents: PDF, DOC, DOCX, TXT, CSV
Audio: MP3, WAV, AAC, OGG
Archives: ZIP, RAR, TAR
Code: JS, CSS, HTML, JSON

You can even store custom file formats – Firebase Storage doesn’t discriminate! 🎯

Setting Up Firebase Storage

Let’s get our hands dirty and set up Firebase Storage in your project.
Before we dive into the code, let’s set up our Firebase project.
To setup the project, you can retrieve this article where I talk about it.

Step 1: Enable Storage in Firebase Console

  1. Go to your Firebase project console
  2. Click on “Storage” in the left sidebar
  3. Click “Get started”
  4. Choose your security rules mode (we’ll configure this properly later)
  5. Select a storage location close to your users

Your storage bucket is now ready! 🚀

Step 2: Configure CORS (if needed)

For web uploads, you might need to configure CORS. Create a cors.json file:

[
  {
    "origin": ["*"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]

Then apply it:

gsutil cors set cors.json gs://your-bucket-name

Basic File Operations

Let’s learn the fundamental operations: upload, download, and delete files.

Step 1: Uploading Files

Here’s how to upload files to Firebase Storage:

import { storage } from './firebase';
import { ref, uploadBytes, uploadBytesResumable, getDownloadURL } from 'firebase/storage';

// Simple file upload
const uploadFile = async (file, path) => {
  try {
    const storageRef = ref(storage, path);
    const snapshot = await uploadBytes(storageRef, file);
    console.log('Upload completed:', snapshot);

    // Get download URL
    const downloadURL = await getDownloadURL(snapshot.ref);
    return { success: true, downloadURL, error: null };
  } catch (error) {
    console.error('Upload failed:', error);
    return { success: false, downloadURL: null, error: error.message };
  }
};

// Upload with progress tracking
const uploadFileWithProgress = (file, path, onProgress) => {
  return new Promise((resolve, reject) => {
    const storageRef = ref(storage, path);
    const uploadTask = uploadBytesResumable(storageRef, file);

    uploadTask.on('state_changed',
      // Progress callback
      (snapshot) => {
        const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        onProgress(progress);
        console.log('Upload is ' + progress + '% done');
      },
      // Error callback
      (error) => {
        reject(error);
      },
      // Success callback
      async () => {
        const downloadURL = await getDownloadURL(uploadTask.snapshot.ref);
        resolve({ downloadURL, snapshot: uploadTask.snapshot });
      }
    );
  });
};

Step 2: Downloading Files

Here’s how to retrieve files from Firebase Storage:

import { ref, getDownloadURL, getBlob } from 'firebase/storage';

// Get download URL
const getFileURL = async (path) => {
  try {
    const storageRef = ref(storage, path);
    const url = await getDownloadURL(storageRef);
    return { success: true, url, error: null };
  } catch (error) {
    console.error('Failed to get download URL:', error);
    return { success: false, url: null, error: error.message };
  }
};

// Download file as blob
const downloadFile = async (path) => {
  try {
    const storageRef = ref(storage, path);
    const blob = await getBlob(storageRef);

    // Create download link
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = path.split('/').pop(); // Extract filename
    a.click();

    // Cleanup
    URL.revokeObjectURL(url);

    return { success: true, error: null };
  } catch (error) {
    console.error('Download failed:', error);
    return { success: false, error: error.message };
  }
};

Step 3: Deleting Files

Here’s how to remove files from Firebase Storage:

import { ref, deleteObject } from 'firebase/storage';

// Delete a file
const deleteFile = async (path) => {
  try {
    const storageRef = ref(storage, path);
    await deleteObject(storageRef);
    console.log('File deleted successfully');
    return { success: true, error: null };
  } catch (error) {
    console.error('Delete failed:', error);
    return { success: false, error: error.message };
  }
};

Security Rules for Storage

Let’s set up proper security rules to protect your files! 🛡️

Step 1: Basic Security Rules

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    // Default: only authenticated users can upload/download
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Step 2: User-specific File Access

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    // Users can only access their own files
    match /users/{userId}/{allPaths=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }

    // Public files - anyone can read, only auth users can write
    match /public/{allPaths=**} {
      allow read: if true;
      allow write: if request.auth != null;
    }

    // Profile pictures - readable by all, writable by owner
    match /profiles/{userId}/avatar.jpg {
      allow read: if true;
      allow write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

Step 3: File Type and Size Restrictions

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    // Helper functions
    function isImageFile() {
      return request.resource.contentType.matches('image/.*');
    }

    function isUnder10MB() {
      return request.resource.size < 10 * 1024 * 1024;
    }

    function isAuthenticated() {
      return request.auth != null;
    }

    // User uploads with restrictions
    match /uploads/{userId}/{fileName} {
      allow read: if isAuthenticated();
      allow write: if isAuthenticated() && 
                      request.auth.uid == userId && 
                      isImageFile() && 
                      isUnder10MB();
    }

    // Document uploads
    match /documents/{userId}/{fileName} {
      allow read, write: if isAuthenticated() && 
                            request.auth.uid == userId &&
                            (request.resource.contentType.matches('application/pdf') ||
                             request.resource.contentType.matches('application/msword') ||
                             request.resource.contentType.matches('text/.*')) &&
                            request.resource.size < 50 * 1024 * 1024; // 50MB limit
    }
  }
}

Conclusion

You now have a working Firebase Storage setup: upload files with progress, fetch download URLs, organize content, secure access with rules, and run it all locally with the emulator.

Happy coding!✨

Hi👋🏻
My name is Domenico, software developer passionate of Open Source, I write article about it for share my knowledge and experience.
Don’t forget to visit my Linktree to discover my projects 🫰🏻

Linktree: https://linktr.ee/domenicotenace

Follow me on dev.to for other articles 👇🏻

If you like my content or want to support my work on GitHub, you can support me with a very small donation.
I would be grateful 🥹

Buy Me A Coffee

Similar Posts