0

I have created a project that uses MongoDB to store user info and Next-Auth to authenticate users. On local host this is all working seamlessly. Previously I had a couple errors with my next-auth config, but that seems to be working fine now on Vercel live site. Once the user logs in they are redirected to "my-project/suggestions". On this page I am using getServerSideProps to identify if there is a valid session token. If so, data is pulled from a local json file.

On the live site, when the user logs in, the page is redirected to "/suggestions", yet I am receiving an 500 Internal Server Error page. On the function logs I am getting this error message:

[GET] /_next/data/KpsnuV9k44lUAhQ-0rK-B/suggestions.json
10:10:57:12
2022-05-05T14:10:59.270Z    5b7a7375-045f-4518-864b-7968c3c9385f    ERROR   [Error: ENOENT: no such file or directory, open '/var/task/public/data/data.json'] {
  errno: -2,
  syscall: 'open',
  path: '/var/task/public/data/data.json',
  page: '/suggestions'
}
RequestId: 5b7a7375-045f-4518-864b-7968c3c9385f Error: Runtime exited with error: exit status 1
Runtime.ExitError

This is my first project using MongoDB and Next-Auth.. not so sure what the issue is in this case. In my .env.local file I only have these two variables:

NEXTAUTH_SECRET="MUNKNATION" NEXTAUTH_URL=http://localhost:3000

How I am pulling the data on local host:

export const getServerSideProps = async (context) => {
  const session = await getSession({ req: context.req });

  if (!session) {
    return {
      redirect: {
        destination: "/",
        permanent: false,
      },
    };
  } else {
    let filePath = path.join(process.cwd(), "public", "data", "data.json");

    let jsonData = await fs.readFile(filePath);

    const data = JSON.parse(jsonData);

    const inProgressStatusData = data.productRequests.filter(
      (item) => item.status == "in-progress"
    );

    const liveStatusData = data.productRequests.filter(
      (item) => item.status == "live"
    );

    const plannedStatusData = data.productRequests.filter(
      (item) => item.status == "planned"
    );

    let filterData = filteredData(data, "suggestion");

    let feedbackData = {
      suggestions: filterData,
      progress: inProgressStatusData,
      planned: plannedStatusData,
      live: liveStatusData,
    };

    return {
      props: { session, feedbackData },
    };
  }
};


Folder structure:

enter image description here

Felipe
  • 333
  • 7
  • 19
  • It seems like you are not specifying your local JSON data file correctly. What is the path from where you are pulling your local JSON file locally? – Am4teur May 06 '22 at 15:34
  • Also, could you show us how you pull data from the JSON file? it might be that – Am4teur May 06 '22 at 15:50
  • Hey @Am4teur, thanks for reaching out. I just edited my question, please see above ^ – Felipe May 06 '22 at 17:42
  • Maybe I need to add a src folder containing all public, pages, and components? – Felipe May 06 '22 at 17:42
  • @Am4teur if you got time to review my edited question I would greatly appreciate it – Felipe May 08 '22 at 03:20
  • Hey @Felipe, it is going to be a bit difficult to help you because I cannot test the "solutions"/fixes I am going to propose. So you will have to test them. 1. Your error seems to come from the line `let filePath = path.join(process.cwd(), "public", "data", "data.json");` because it says that it cannot "open '/var/task/public/data/data.json'" You probably want to open '/public/data/data.json' but instead you are opening '/var/task/public/data/data.json' So make sure if the process.cwd() is really needed in the path file. – Am4teur May 09 '22 at 10:09
  • 2. look into this: https://vercel.com/support/articles/how-can-i-use-files-in-serverless-functions Check if you can apply this and if it fixes the problem – Am4teur May 09 '22 at 10:09
  • Meanwhile im going to create a dummy project just to test a few edge cases and ill get back to you as soon as i can – Am4teur May 09 '22 at 10:10

1 Answers1

0

A simple solution to this problem would be to, inside of your getServerSideProps, instead of calling readFile use readFileSync as follows:

export const getServerSideProps = async (context) => {
...
    const file = readFileSync(
      join(process.cwd(), "public", "data", "data.json"),
      "utf8"
    );
    const data = JSON.parse(fileData);
...

I have tested this solution with Vercel and it works correctly, in development and production mode.

Am4teur
  • 125
  • 1
  • 9