Description
<!--
DO NOT DELETE
validate_template=true
template_path=.github/ISSUE_TEMPLATE/bug_report.md
-->
[REQUIRED] Environment info
firebase-tools: 13.31.1
Platform: Windows
[REQUIRED] Test case
I am using Next js 15
The issues is getting data from firebase into server comps on dynamic pages
I can get the slug from the URL but if I use a server action to get any data from firebase, It will show 500 Internal Server Error only in PRODUCTION
This 500 Internal Server Error is not seen in the development and firebase emulator.
I cant get firebase data into a dynamic page routes without getting a 500 error from the server in PRODUCTION
Static routes are able to get data from Firebase without the 500 Error
Using App router in NEXT JS 15
// app/meettheteam/[id]/page.tsx (Server Component)
import type { Coach } from '@/types';
import { getCoachById } from '@/lib/coaches-data';
import CoachComp from './CoachComp';
import { Suspense } from 'react';
import { notFound } from 'next/navigation';
async function CoachPage({ params }: { params: Promise<{ id: string }> }) {
const id = (await params).id;
try {
const coach: Coach | null = await getCoachById(id);
if (!coach) {
notFound();
return;
}
return (
<>
<Suspense fallback={<p>Loading coach details...</p>}>
<CoachComp coach={coach} />
</Suspense>
</>
);
} catch (error) {
console.error('Error fetching coach:', error);
return <div>Error loading coach. Please try again later.</div>;
}
}
export default CoachPage;
'use server';
// lib/coaches-data.ts
import { DocumentData } from 'firebase/firestore';
import { db } from '@/config/firebaseServer';
const getCoaches = async () => {
try {
const snapshot = await db.collection('coaches').get();
if (snapshot.empty) {
console.log('No matching documents.');
return;
}
const coachesDocs: DocumentData[] = snapshot.docs;
const coaches = coachesDocs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
return coaches;
} catch (error) {
console.error('Error fetching coachs:', error);
throw error;
}
};
const getCoachById = async (id: string) => {
try {
const coachDoc: DocumentData = await db.collection('coaches').doc(id).get();
if (coachDoc.exists) {
const coach = coachDoc.data();
coach.id = coachDoc.id;
return coach;
} else {
console.log('Coach not found with ID:', id);
return null;
}
} catch (error) {
console.error('Error in getCoachById:', error);
throw error;
}
};
export { getCoaches, getCoachById };
// config/firebaseServer.tsx
import { initializeApp, getApps } from 'firebase-admin/app';
import { getAuth } from 'firebase-admin/auth';
import { getFirestore } from 'firebase-admin/firestore';
import { getStorage } from 'firebase-admin/storage';
import { credential } from 'firebase-admin';
function initializeFirebaseAdmin() {
const projectId = process.env.FIREBASE_PROJECT_ID;
const storageBucket = process.env.FIREBASE_STORAGE_BUCKET;
if (!projectId || !storageBucket) {
// Check for these
console.error(
'Missing required Firebase environment variables (projectId or storageBucket).',
);
throw new Error(
'Missing required Firebase environment variables (projectId or storageBucket).',
);
}
try {
const serviceAccount = require('../firebase.json'); // Directly require the JSON
if (getApps().length === 0) {
initializeApp({
credential: credential.cert(serviceAccount),
projectId,
storageBucket,
});
console.log('Firebase Admin initialized successfully.');
} else {
console.log('Using existing Firebase Admin app.');
}
} catch (error) {
console.error('Error initializing Firebase Admin:', error);
throw error;
}
}
initializeFirebaseAdmin();
const admin = getAuth();
const db = getFirestore();
const storage = getStorage();
export { admin, db, storage };
[REQUIRED] Steps to reproduce
Create Next JS app
Create dynamic page routes in app folder
use the dynamic slug as ID for a document in a collection
Create server action to get doc from collection into a server comp on dynamic page route
Pass data to client comp for display
[REQUIRED] Expected behavior
dynamic routes use the slugs as ID for a document in a collection
Server comp on dynamic page uses slug for ID to get data from server action using firebase
Data passed into client comp
Data displayed in client comp
[REQUIRED] Actual behavior
500 Internal Server Error