Next.js Discord

Discord Forum

`npm run build` succeeds but `vercel build` fails

Answered
Oriental posted this in #help-forum
Open in Discord
OrientalOP
this is a followup to https://nextjs-forum.com/post/1224490069826470012#message-1224490069826470012

I have tried all the suggested changes and it's still failing with the following error:

Collecting page data  ..SyntaxError: Unexpected token
 in JSON at position 42
    at JSON.parse (<anonymous>)
    at 7201 (/Users/kayvan/Development/Repos/smog.net/.next/server/app/api/shop/route.js:1:489)


here is my beare minimum code that fails:
// /api/shop/route.ts
import db from "@/app/services/firebase";
import { NextRequest, NextResponse } from "next/server";

export async function POST(request: NextRequest) {
  const existingDoc = await db.collection("abcd").get();

  return NextResponse.json({});
}

// ------
// /shop/page.tsx
"use client";

export default function Home() {
  const stringData = JSON.stringify({});
  const shop = fetch(`${process.env.NEXT_PUBLIC_HOST}/api/shop`, {
    method: "POST",
    body: stringData,
  }).then((response) => {});

  return (
    <>
      <div></div>
    </>
  );
}

I believe I'm missing something fundamental but can't find it! the page is suppose to be a client component! any help is appreciated
Answered by Ray
You need to make sure the firebase instance is initialised in the route like the link above
View full answer

29 Replies

OrientalOP
@Ray if you get a chance to explain this a bit more it would help tremendously
Greenish Elaenia
Error is saying JSON.parse is unable to parse something - in your code, i dont see "parse"?
My guess is a syntax issue
OrientalOP
neither do I 😦 if I comment out the firebase line
 
const existingDoc = await db.collection("abcd").get();

it builds but when I try to read from db it gives me this error
OrientalOP
"use client";

import { useEffect } from "react";

export default function Home() {
  useEffect(() => {
    const stringData = JSON.stringify({});
    const shop = fetch(`${process.env.NEXT_PUBLIC_HOST}/api/shop`, {
      method: "POST",
      body: stringData,
    }).then((response) => {});
  }, []);

  return (
    <>
      <div></div>
    </>
  );
}

still failing
And you dont need the full url when you fetching on client. You can do this fetch(/api/shop)
OrientalOP
Thank you for the suggestions, however I just applied both of these and the error is still present
"use client";

import { useEffect } from "react";

export default function Home() {
  useEffect(() => {
    const stringData = JSON.stringify({});
    const shop = fetch(`/api/shop`, {
      method: "POST",
      body: stringData,
    }).then((response) => {});
  }, []);

  return (
    <>
      <div></div>
    </>
  );
}
Could you show the code of db
OrientalOP
sure:
import * as admin from "firebase-admin";
import { getApps, getApp } from "firebase-admin/app";

const privateKey = JSON.parse(process.env.FIREBASE_PRIVATE_KEY || "");

// Initialize Firebase

export const app = !getApps().length
  ? admin.initializeApp({
      credential: admin.credential.cert({
        clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
        privateKey: privateKey.privateKey,
        projectId: "some-project-id",
      }),
    })
  : getApp();

const db = admin.firestore();

export default db;
export const storage = admin.storage();
I don't understand how the npm build works and also functionality wise it all works but when I do vercel build it fails!!!
OrientalOP
same exact error.
import db from "@/app/services/firebase";
import { NextRequest, NextResponse } from "next/server";

export async function POST(request: NextRequest) {
  try {
    const existingDoc = await db.collection("abcd").get();
  } catch (error) {
    return NextResponse.json({});
  }
  return NextResponse.json({});
}
it's not the methods on the query neither, but as soon as I not make the query it succeeds
import db from "@/app/services/firebase";
import { NextRequest, NextResponse } from "next/server";

export async function POST(request: NextRequest) {
  try {
    const docCount = await db.collection("admins").count();
    return NextResponse.json(docCount);
  } catch (error) {
    return NextResponse.json({});
  }
  return NextResponse.json({});
}
as you can see it works in dev mode too:
import db from "@/app/services/firebase";
import { NextRequest, NextResponse } from "next/server";

export async function POST(request: NextRequest) {
  try {
    const docCount = await db.collection("admins").count().get();
    return NextResponse.json(docCount.data().count);
  } catch (error) {
    return NextResponse.json({});
  }
  return NextResponse.json({});
}
removing the fetch from client component all-together didn't help neither.
I think someting wrong with the firebase setup
OrientalOP
I'll give it a shot. Thank you.
I think you need to init the firebase in the route handler
OrientalOP
let me inline the init then
@Oriental let me inline the init then
Yeah you could try it first
OrientalOP
that worked!!! inlining it in the route.
import { NextRequest, NextResponse } from "next/server";
import * as admin from "firebase-admin";
import { getApps, getApp } from "firebase-admin/app";

export async function POST(request: NextRequest) {
  const privateKey = JSON.parse(process.env.FIREBASE_PRIVATE_KEY || "");

  // Initialize Firebase

  const app = !getApps().length
    ? admin.initializeApp({
        credential: admin.credential.cert({
          clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
          privateKey: privateKey.privateKey,
          projectId: "some-app",
        }),
      })
    : getApp();

  const db = admin.firestore();

  try {
    const docCount = await db.collection("admins").count().get();
    return NextResponse.json(docCount.data().count);
  } catch (error) {
    return NextResponse.json({});
  }
  return NextResponse.json({});
}
do you have any idea of why?
Because vercel is a serverless platform
You need to make sure the firebase instance is initialised in the route like the link above
Answer
OrientalOP
thank you so much for helping.
Np