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
- Go to your Firebase project console
- Click on “Storage” in the left sidebar
- Click “Get started”
- Choose your security rules mode (we’ll configure this properly later)
- 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 🥹