I’ve been working on a firebase+next.js application, but the only API endpoint I’ve defined returns empty no matter what (even if I make it return dummy static data).
Here is what I did:
inside the app folder, created an api folder, and inside api created users folder.
inside users, there is just route.js
.
// This is where you get the data from the API to the frontend.
import { firestore } from "@/firebase/server";
import { NextRequest, NextResponse } from "next/server";
// DummyData to test the API connection.
export type userOverview = {
firstName: String,
lastName: String,
}
const defaultUsersFirst: userOverview[] = [
{
"firstName": "John",
"lastName": "Doe",
}
]
export async function GET(request: NextRequest){
try{
if (!firestore){
return new NextResponse("Internal Error: no firestore", {status:500});
}
const response = await firestore.collection("users").get();
const users = response.docs.map((doc) => doc.data());
console.log(users)
console.log(defaultUsersFirst);
// no data in the emulator. add dummy data.
if(users.length <= 0){
const batch = firestore.batch();
defaultUsersFirst.forEach((user) => {
const userRef = firestore?.collection("users").doc();
if(userRef) batch.set(userRef, user);
})
batch.commit();
return NextResponse.json(defaultUsersFirst);
}
return NextResponse.json(users);
} catch (error){
return new NextResponse("Internal Error", {status: 500});
}
}
then, inside app there is also a users folder for endpoint inside which there is only a page.tsx
.
That one looks like this:
import { userOverview } from "../api/users/route";
import Table from "@/components/table";
export default async function Users() {
let users: userOverview[] = [];
const response = await fetch(`${process.env.API_URL}/api/users`);
if (response.ok) {
// debug
console.log("getting response json")
const usersJson = await response.json();
users = usersJson;
console.log(usersJson)
} else {
console.error('Failed to fetch users:', response.statusText);
}
return (
<div className="flex flex-col items-center mt-8">
{users.toString()}
</div>
);
}
Now using these logs I’ve wrote here, I was able to see that whatever fetched from the users api is always empty.
Regarding my setups is, I can connect to the local emulator from my web, and I’ve installed necessary dependencies while setting up firebase init
. Moreover, I also did npm install firebase firebase-admin
just to be safe as well.
To categorize the code properly, inside the root project directory, I’ve created a firebase folder inside which there is a file called serviceAccount.json
which is the secret key for admin sdk generated by firebase project.
the functions folder you get when you setup firebase is also inside this folder.
Finally, inside this folder there is server.ts
:
import serviceAccount from "./serviceAccount.json";
import { initializeApp, ServiceAccount, cert, getApps } from "firebase-admin/app";
import { Firestore, getFirestore } from "firebase-admin/firestore";
let firestore : Firestore | undefined = undefined;
const currentApps = getApps();
if (currentApps.length <= 0) {
if (process.env.NEXT_PUBLIC_APP_ENV === "emulator") {
process.env["FIRESTORE_EMULATOR_HOST"] =
process.env.NEXT_PUBLIC_EMULATOR_FIRESTORE_PATH;
process.env["FIREBASE_AUTH_EMULATOR_HOST"] =
process.env.NEXT_PUBLIC_EMULATOR_AUTH_PATH;
}
const app = initializeApp({
credential: cert(serviceAccount as ServiceAccount),
});
firestore = getFirestore(app);
console.log("firestore working");
} else {
firestore = getFirestore(currentApps[0]);
console.log("firestore working");
}
export { firestore };
some extra information that might be necessary is my .env.development looks like this:
API_URL=http://localhost:3000
NEXT_PUBLIC_EMULATOR_FIRESTORE_PATH=127.0.0.1:8080
NEXT_PUBLIC_EMULATOR_AUTH_PATH=127.0.0.1:9099
aind I’ve adjusted my package.json to set the work environment to developing so that I can use emulator and not the actual firestore.
package.json:
...
"scripts": {
"dev": "NEXT_PUBLIC_APP_ENV='emulator' next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"emulators": "firebase emulators:start"
},
...
To give some idea on project structure, I’ve addedd the folder structure from root directory as image.
Thank you for your time.
As can be seen above, I’ve tried to setup the api endpoint in a way such that if firestore collection is empty, add dummy data to it and return it. However, now it always returns empty.
4batzthatsit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.