Skip to content
Advertisement

How do I get data from Firebase collection using NextJs API, Firebase Firestore, axios and TypeScript?

I’m using api routes in NextJS 13, to fetch data from Firebase like this(api/locations.tsx):

import { db } from "../../firebase";
import { collection, getDocs } from "firebase/firestore";
import type { NextApiRequest, NextApiResponse } from "next";

const Locations = async (req: NextApiRequest, res: NextApiResponse) => {
  try {
    const locationsSnapshot = await getDocs(collection(db, "locations"));
    const locationsData = locationsSnapshot.docs.map((doc) => ({
      ...doc.data(),
      id: doc.id,
    }));

    res.status(200).json({ locationsData });
  } catch {
    res.status(400).end();
  }
};

export default Locations;

Then I have a component Locations.tsx where I’m trying to store the locations in locations state object like this:

import { useEffect, useState } from "react";
import Link from "next/link";
import {
  Container,
  Content,
  Main,
  StyledLink,
  Title,
} from "../components/sharedstyles";
import axios from "axios";

export type LocationData = {
  film: string;
  imdbId: string;
  location?: string;
  scene?: string;
  coords: [number, number];
}[];

type GetLocationResponse = { data: { locationsData: LocationData[] } };

export default function About() {
  const [locations, setLocations] = useState([]);

  const getLocations = async () => {
    // Fetch locations data from locations endpoint and return location data
    const res = await axios.get<GetLocationResponse>("/api/locations");

    return res.data.locationsData;
  };

  useEffect(() => {
    setLocations(getLocations());
  }, []);

  return (
    <Container>
      <Main>
        <Title>Locations</Title>
        <Content>
          <ul>
            {locations?.map(({ location }) => (
              <li>{location}</li>
            ))}
          </ul>
        </Content>
        <Link href="/" passHref legacyBehavior>
          <StyledLink>&larr; Home</StyledLink>
        </Link>
      </Main>
    </Container>
  );
}

But I’m getting an error Property 'locationsData' does not exist on type 'GetLocationResponse'. even though I tried adding “locationsData” to my type definition type GetLocationResponse = { data: { locationsData: LocationData[] } };

Can anyone tell me why I’m getting this error and how I might resolve it? Please and thanks!

Advertisement

Answer

Your frontend is expecting a response object with a data property:

type GetLocationResponse = { data: { locationsData: LocationData[] } };

But your backend is sending and object with only a property locationsData:

res.status(200).json({ locationsData });

Perhaps you want the frontend’s expectations to match what the backend is sending by dropping the data property:

type GetLocationResponse = { locationsData: LocationData[] };
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement