0

I built a React web app that allows users the calculate their meal's nutrition.

Users enter an ingredient in the IngredientForm component, triggering the fetchFirebaseNutrition function.

const fetchFirebaseNutrition = (ingredientName) => {
    const axios = require('axios');

    const options = {
      method: 'GET',
      url: 'http://localhost:5001/nutrition-calculator-6db9d/us-central1/fetchAPINutrition',
      params: { ingredient: ingredientName },
    };

    return axios
      .request(options)
      .then((response) => {
        console.log(response);
      })
      .catch((error) => {
        console.error(error);
        return setIsAPIConnectionDown(true);
      });
  };

fetchFirebaseNutrition makes a get request to to my Firebase function, fetchAPINutrition, with the relevant ingredient. Then, fetchAPINutrition makes a get request to an API for the nutrition data. I'm using the Firebase function to conceal the API key for when I deploy my web app.

exports.fetchAPINutrition = functions.https.onRequest((req, res) => {
  const axios = require('axios');
  const ingredient = req.query.ingredient;

  const options = {
    method: 'GET',
    url: 'https://calorieninjas.p.rapidapi.com/v1/nutrition',
    params: { query: ingredient },
    headers: {
      'X-RapidAPI-Host': 'calorieninjas.p.rapidapi.com',
      'X-RapidAPI-Key': process.env.REACT_APP_RAPID_API_KEY,
    },
  };

  return axios
    .request(options)
    .then((response) => {
      console.log(response.data);
      return response.data;
    })
    .catch((error) => {
      console.error(error);
    });
});

fetchAPINutrition works... kind of. When I make a request to the function from the front-end, I can see on the Firebase Emulator that fetchAPINutrition is successfully getting the data from the API. See the Firebase Emulator Logs. However, the function just times out afterwards. So, fetchFirebaseNutrition never receives the API data and just returns an Axios Network Error message.

How can I stop my Firebase function from timing out and return the API data to the front-end?

Any help would be immensely appreciated!

Robert
  • 3
  • 2
  • The programmer must always explicitly terminate these cloud functions by either returning a `Promise` or throwing an `HttpsError` according to the requirements of Firebase (throwing any kind of https error won't do). If you aren't doing either of these two things then your functions will always timeout. – trndjc Sep 13 '22 at 18:14

1 Answers1

2

HTTPS functions expect a return, which you don't. Instead, you are returning a promise without waiting for it to complete.

You need to return a result.

res.status(200).send(response.data);

In this case;

axios
.request(options)
.then((response) => {
  res.status(200).send(response.data);
})
.catch((error) => {
  console.error(error);
  res.status(500).send("Error");
});
siniradam
  • 2,727
  • 26
  • 37
  • Thank you, this resolved the timeout issue! As a side note, I still got a Axios Network Error message after adding your code, but I just added res.set('Access-Control-Allow-Origin', '*') to fetchAPINutrition and everything worked after that – Robert Sep 13 '22 at 19:48
  • @Robert That's a CORS issue, it isn't related to the problem described here. Check out the cors package from NPM or this; https://stackoverflow.com/questions/42755131/enabling-cors-in-cloud-functions-for-firebase – siniradam Sep 15 '22 at 01:46