Simple Image Upload with Firebase in Next.js

In this tutorial, we’ll walk through the steps to create a simple image upload feature using Firebase and Next.js. This guide is perfect for beginners who want to enhance their web development skills by integrating Firebase into a Next.js project.

Filip Jerga
Eincode
4 min readMay 17, 2024

--

Introduction

Uploading images is a common feature in many web applications. By using Firebase and Next.js, we can create a robust and efficient image upload system. Firebase provides a scalable backend solution, while Next.js offers a powerful framework for building React applications.

In this post, we’ll cover:

  • Setting up a Firebase project
  • Integrating Firebase with Next.js
  • Implementing the image upload functionality
  • Viewing uploaded images in a gallery

Resources

Video Tutorial:https://youtu.be/Y-kwlvhR7Z0

Full Courses: https://academy.eincode.com/

Prerequisites

Before we begin, make sure you have the following:

  • Basic knowledge of React and Next.js
  • A Firebase account
  • Node.js and npm installed on your machine

Step 1: Setting Up Firebase

First, you need to create a Firebase project. Follow these steps:

  1. Go to the Firebase Console.
  2. Click on “Add project” and follow the prompts to create a new project.
  3. Once your project is created, navigate to the “Storage” section and click on “Get started” to enable Firebase Storage.

Next, you’ll need to add a Firebase configuration file to your Next.js project:

  1. Click on the “Settings” icon in the Firebase Console and select “Project settings”.
  2. Under “Your apps”, click on the web icon to create a new web app.
  3. Copy the Firebase configuration object.

Step 2: Integrating Firebase with Next.js

Create a new Next.js project if you don’t already have one:

npx create-next-app next-firebase-image-upload
cd next-firebase-image-upload

Install Firebase:

npm install firebase

Create a firebaseConfig.js file in the src/app directory and add the Firebase configuration:

// src/app/firebaseConfig.js

import { initializeApp } from "firebase/app";
import { getStorage } from "firebase/storage";

// Your Firebase configuration object
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"
};

// Initialize Firebase app
const app = initializeApp(firebaseConfig);

// Get a reference to the storage service
const storage = getStorage(app);

export { storage };

Step 3: Creating the Home Page

Create a page.js file in the src/app directory to serve as the home page:

Step 4: Implementing the Image Upload Page

Create an upload/page.js file in the src/app directory to handle image uploads:

"use client"

import Image from "next/image";
import { useState } from "react";
import { ref, uploadBytes, getDownloadURL } from "firebase/storage";
import { storage } from "../firebaseConfig";

export default function Upload() {
const [file, setFile] = useState(null); // State to store the selected file
const [uploading, setUploading] = useState(false); // State to indicate the upload status
const [uploadedUrl, setUploadedUrl] = useState(null); // State to store the uploaded image URL

const handleFileChange = (event) => {
setFile(event.target.files[0]); // Set the selected file
};

const handleUpload = async () => {
if (!file) return; // Return if no file is selected

setUploading(true); // Set uploading state to true
const storageRef = ref(storage, `images/${file.name}`); // Create a reference to the file in Firebase Storage

try {
await uploadBytes(storageRef, file); // Upload the file to Firebase Storage
const url = await getDownloadURL(storageRef); // Get the download URL of the uploaded file
setUploadedUrl(url); // Set the uploaded image URL
console.log("File Uploaded Successfully");
} catch (error) {
console.error('Error uploading the file', error);
} finally {
setUploading(false); // Set uploading state to false
}
};

return (
<div>
<input type="file" onChange={handleFileChange} /> {/* File input to select the image */}
<button onClick={handleUpload} disabled={uploading}>
{uploading ? "Uploading..." : "Upload Image"} {/* Button to upload the image */}
</button>
{uploadedUrl && (
<div>
<p>Uploaded image:</p>
<Image
src={uploadedUrl}
alt="Uploaded image"
width={300}
height={300}
layout="responsive"
/>
</div>
)}
</div>
);
}

Step 5: Creating the Gallery Page

Create a gallery/page.js file in the src/app directory to display uploaded images:

"use client"

import { listAll, ref, getDownloadURL } from "firebase/storage";
import { useEffect, useState } from "react";
import { storage } from "../firebaseConfig";
import Image from "next/image";

export default function Gallery() {
const [images, setImages] = useState([]); // State to store the list of image URLs

useEffect(() => {
const fetchImages = async () => {
const imagesRef = ref(storage, "images/"); // Reference to the images directory in Firebase Storage

try {
const result = await listAll(imagesRef); // List all items in the images directory
const urls = await Promise.all(result.items.map(item => getDownloadURL(item))); // Get the download URLs for all images
setImages(urls); // Set the list of image URLs
} catch (error) {
console.error("Error fetching images", error);
}
};

fetchImages(); // Fetch images when the component mounts
}, []);

return (
<div>
<h1>Gallery</h1>
<div style={{ display: "flex", flexDirection: "row" }}>
{images.map((url, index) => (
<div key={url} style={{ margin: 10, position: 'relative', width: '300px', height: '500px' }}>
<Image
src={url}
alt={`Image ${index}`}
sizes="300px"
fill
style={{
objectFit: 'contain',
}}
/>
</div>
))}
</div>
</div>
);
}

Conclusion

You now have a simple image upload feature integrated into your Next.js application using Firebase. This setup includes the ability to upload images and view them in a gallery. You can expand this with additional functionality like user authentication, file metadata, and more advanced error handling.

Feel free to check out the GitHub repository for the complete code.

If you found this tutorial helpful, please give it a clap and share it with others. Stay tuned for more tutorials and tips on web development!

--

--