Skip to content

Instantly share code, notes, and snippets.

@joeschoe
Last active March 28, 2024 17:00
Show Gist options
  • Save joeschoe/7939469465ce44a3f533b1690ed12dd2 to your computer and use it in GitHub Desktop.
Save joeschoe/7939469465ce44a3f533b1690ed12dd2 to your computer and use it in GitHub Desktop.
Upload images to firebase storage with next app router, server components, and server actions
// Use next app router, server components, and server actions to upload files to firebase storage
//
// you probably dont want to do this since just storing images in the next public folder is usually best
// but if for some reason you need to upload files to firebase storage from nextjs, here you go
// also worth noting that the firebase-admin storage sdk has almost no documentation
// and from what I can tell does almost nothing, but it's just a wrapper around the google cloud storage sdk
// so you can use that instead if you want better documentation and functionality
import { Readable } from "stream";
import { getDownloadURL } from "firebase-admin/storage";
import { storage } from "@/lib/firebase-admin-config"; // described below
export default async function Upload() {
async function handleFormData(formData: FormData) {
"use server";
const file = formData.get("file") as File;
const bytes = await file.arrayBuffer();
const buffer = Buffer.from(bytes);
const stream = Readable.from(buffer);
// get your bucket name
// firebase console > storage > files, bucket name is at the top of the table
// looks like something.appspot.com
// remove the gs:// prefix
const destination = storage.bucket("YOUR_BUCKET_NAME").file(file.name);
const upload = await new Promise(function (resolve, reject) {
stream
.pipe(destination.createWriteStream())
.on("error", function (err) {
reject(err);
})
.on("finish", function () {
resolve("uploaded");
});
});
// this is the url you can use to display the image in a website and so forth
const url = await getDownloadURL(destination);
console.log(url);
}
return (
<main>
<h1>Upload an image ok</h1>
<form action={handleFormData}>
<label>
<input
type="file"
name="file"
accept="image/png, image/jpeg, image/gif"
/>
</label>
<button type="submit">Submit</button>
</form>
</main>
);
}
// firebase-admin-config set up
import { initializeApp, getApps, cert } from "firebase-admin/app";
import { getStorage } from "firebase-admin/storage";
// get service account
// firebase console > project settings > service accounts tab > generate new private key button
// save the file > rename it service_account.json > put in the root of yr project
import serviceAccount from "@/service_account.json";
const firebaseAdminConfig = {
credential: cert({
privateKey: serviceAccount.private_key,
clientEmail: serviceAccount.client_email,
projectId: serviceAccount.project_id,
}),
};
const app =
getApps().length <= 0 ? initializeApp(firebaseAdminConfig) : getApps()[0];
export const storage = getStorage(app);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment