I have successfully uploaded files to Google Drive using their API and configured public sharing permissions. However, my frontend crashes whenever I attempt to render these images. This has been an ongoing issue for multiple days without any resolution.
import { google } from "googleapis";
import { NextRequest, NextResponse } from "next/server";
import { Readable } from "stream";
const SHEET_ID = process.env.SHEET_ID!;
const CLIENT_EMAIL = process.env.CLIENT_EMAIL!;
const PRIVATE_KEY = process.env.PRIVATE_KEY!.replace(/\\n/g, "\n");
const FOLDER_ID = process.env.FOLDER_ID!;
export async function POST(request: NextRequest) {
try {
const data = await request.formData();
const username = data.get("username") as string;
const userEmail = data.get("userEmail") as string;
const content = data.get("content") as string;
const uploadedFile = data.get("image") as File | null;
if (!username || !userEmail || !content) {
return NextResponse.json({ error: "Required fields missing" }, { status: 400 });
}
const credentials = new google.auth.JWT(
CLIENT_EMAIL,
undefined,
PRIVATE_KEY,
[
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/drive",
]
);
const sheetsApi = google.sheets({ version: "v4", auth: credentials });
const driveApi = google.drive({ version: "v3", auth: credentials });
let fileUrl = "";
if (uploadedFile && uploadedFile.size > 0) {
const fileBuffer = Buffer.from(await uploadedFile.arrayBuffer());
const result = await driveApi.files.create({
requestBody: {
name: uploadedFile.name,
parents: [FOLDER_ID],
},
media: {
mimeType: uploadedFile.type,
body: Readable.from(fileBuffer),
},
fields: "id",
});
const uploadedFileId = result.data.id;
if (uploadedFileId) {
await driveApi.permissions.create({
fileId: uploadedFileId,
requestBody: {
role: "reader",
type: "anyone",
},
});
fileUrl = `https://drive.google.com/uc?export=view&id=${uploadedFileId}`;
}
}
await sheetsApi.spreadsheets.values.append({
spreadsheetId: SHEET_ID,
range: "Data!A:D",
valueInputOption: "USER_ENTERED",
requestBody: {
values: [[username, userEmail, content, fileUrl]],
},
});
return NextResponse.json({ success: true }, { status: 200 });
} catch (err) {
return NextResponse.json({ error: "Upload failed" }, { status: 500 });
}
}
I attempted to retrieve and display the images through a separate API endpoint:
import { google } from "googleapis";
import { NextResponse } from "next/server";
export async function GET() {
const auth = new google.auth.JWT(
process.env.CLIENT_EMAIL,
undefined,
process.env.PRIVATE_KEY!.replace(/\\n/g, "\n"),
["https://www.googleapis.com/auth/spreadsheets.readonly"]
);
const sheetsClient = google.sheets({ version: "v4", auth });
const result = await sheetsClient.spreadsheets.values.get({
spreadsheetId: process.env.SHEET_ID,
range: "Data!A2:D",
});
const records = result.data.values || [];
const formattedData = records.map((record) => ({
username: record[0],
email: record[1],
content: record[2],
imageLink: record[3],
}));
return NextResponse.json(formattedData);
}
"use client";
import { Box, Image, Stack } from "@mantine/core";
import { useEffect, useState } from "react";
interface DataRecord {
username: string;
email: string;
content: string;
imageLink: string;
}
export default function DisplayPage() {
const [records, setRecords] = useState<DataRecord[]>([]);
useEffect(() => {
const loadData = async () => {
const response = await fetch("/api/fetch-data");
const result = await response.json();
setRecords(result);
};
loadData();
}, []);
return (
<Stack>
{records.map((record, index) => (
<Box key={index}>
<Image
width={250}
height={250}
src={record.imageLink}
alt="user upload"
/>
</Box>
))}
</Stack>
);
}