Last active
March 28, 2024 17:00
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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