Handling File Uploads in Next.js with Firebase Storage
Thursday, January 30, 2025
Uploading files is a common feature in modern web applications, whether for profile pictures, document storage, or media sharing. Firebase Storage offers a scalable and secure way to handle file uploads, making it a great choice for Next.js applications.
In this guide, we’ll walk through setting up Firebase Storage, integrating it with a Next.js app, and implementing a file upload system.
Setting Up Firebase Storage
Before integrating Firebase Storage in our Next.js app, we need to set it up in Firebase.
Step 1: Create a Firebase Project
Step 2: Enable Firebase Storage
Step 3: Get Firebase Config for Next.js
Installing Firebase SDK in Next.js
Run the following command in your Next.js project to install Firebase:
npm install firebase
Now, create a Firebase configuration file to initialize Firebase in your project.
// firebaseConfig.js
import { initializeApp } from "firebase/app";
import { getStorage } from "firebase/storage";
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_STORAGE_BUCKET",
messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
appId: "YOUR_APP_ID",
};
const app = initializeApp(firebaseConfig);
const storage = getStorage(app);
export { storage };
Creating the Upload Form in Next.js
Now, let's create a file upload form.
import { useState } from "react";
export default function FileUpload({ onFileSelect }) {
const [file, setFile] = useState(null);
const handleFileChange = (event) => {
setFile(event.target.files[0]);
};
const handleSubmit = (event) => {
event.preventDefault();
if (file) {
onFileSelect(file);
}
};
return (
<form onSubmit={handleSubmit} className="space-y-4">
<input type="file" onChange={handleFileChange} />
<button type="submit">Upload</button>
</form>
);
}
This component allows users to select a file and trigger the upload function.
Uploading Files to Firebase Storage
Now, let's create a function to upload files to Firebase Storage.
import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
import { storage } from "../firebaseConfig";
export function uploadFile(file, onProgress, onComplete, onError) {
const storageRef = ref(storage, `uploads/${file.name}`);
const uploadTask = uploadBytesResumable(storageRef, file);
uploadTask.on(
"state_changed",
(snapshot) => {
const progress =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
onProgress(progress);
},
(error) => {
onError(error);
},
async () => {
const downloadURL = await getDownloadURL(uploadTask.snapshot.ref);
onComplete(downloadURL);
}
);
}
Retrieving and Displaying Uploaded Files
Once the upload is complete, we can display the uploaded files using their download URLs.
import { useState } from "react";
import { uploadFile } from "../utils/uploadFile";
export default function UploadComponent() {
const [progress, setProgress] = useState(0);
const [fileURL, setFileURL] = useState("");
const handleFileUpload = (file) => {
uploadFile(
file,
(progress) => setProgress(progress),
(url) => setFileURL(url),
(error) => console.error("Upload error:", error)
);
};
return (
<div>
<h2>Upload a File</h2>
<FileUpload onFileSelect={handleFileUpload} />
{progress > 0 && <p>Upload Progress: {progress}%</p>}
{fileURL && <img src={fileURL} alt="Uploaded File" />}
</div>
);
}
Securing File Access
By default, Firebase Storage allows public access, which is not ideal for sensitive files. Update your storage rules to allow only authenticated users to upload and access their files:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /uploads/{userId}/{file} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
This ensures that only authenticated users can access their files.
Conclusion
In this tutorial, we covered:
✅ Setting up Firebase Storage
✅ Integrating Firebase Storage with a Next.js app
✅ Handling file uploads and tracking progress
✅ Displaying uploaded files
✅ Securing file access with Firebase rules
With these basics in place, you can enhance the upload experience by adding features like multiple file uploads, drag-and-drop support, or file previews. 🚀