1

I'm trying to make a reading from firebase, and get a specific field from a collection record.

I have a function that makes the reading from the firestore (getCityName) and there is another function that calls it, which sends an id and should receive a string (renderCities).

Bottom line, instead of getting a string, I get a Promise, the point is that if I do console.log in getCityName, before the return, I get a String, and in the value returned from getCityName into renderCities, I get a Promise (either way, of course the goal in the end is to get a String and not printing to the console.log).

What is the difference between the things? Why one time I get a String and another time I get a Promise? I tried many things, using 'async' and 'await' or with '.then', but at best it just didn't work, at worst there were all sorts of errors...

Cities.Services.js:

getCity = async (id) => {
  const cityDoc = doc(db, "Cities", id); 
  return getDoc(cityDoc);
};

getCityName = async (id) => {
  const docSnap = await this.getCity(id);
  if (docSnap.data() === undefined || docSnap.data() === null)
    console.log(docSnap.data(), id);
  else {
    console.log(docSnap.data().city_name); //return String
    return docSnap.data().city_name;  //return Promise
  }
};

LocalCommiteHandler.js:

const renderCities = (src) => console.log((CitiesServices.getCityName(src)));
{props.cities.length > 0
          ? props.cities.map((item, index) =>
              renderCities(item)
            )
          : "No Cities."}

Versions: firebase: 9.6.5 react: 17.0.2

Netanel.O
  • 31
  • 3
  • 1
    The `CitiesServices.getCityName(src)` returns a `Promise` here but you are not handling it. Can you share the complete component? It'll be easier to query all city names first and the map in to UI rather than calling an async function in map. – Dharmaraj Sep 11 '22 at 05:45
  • @Dharmaraj, The code is currently quite lean, I have listed above the relevant function for reading using getDoc, the other functions in the class simply add / update, etc. Regarding your proposal, to read all the names of the cities into a map (or a dictionary), I made such an attempt, I've used a useState array, but other errors appeared there (infinite loop, etc.), I preferred the way that seems the simplest to me at the moment, in particular that I will use with this model for other functions. If you have any other ideas, I'd love to hear them. – Netanel.O Sep 11 '22 at 06:15
  • Could share the complete component with that attempt? The component wiht `props.cities...` . – Dharmaraj Sep 11 '22 at 06:18
  • @Dharmaraj, props.cities is a small part of a relatively large JSX section, it contain mainly design elements. props.cities gets its data from 'behind' components, I can write if it helps but I don't think it's necessary. props.cities returns an array of city ids from a firestore collection. I know that the retrieved information is correct since I did a test using console.log on the retrieved information and saw that it is correct, when it is displayed in Cities.Services, before sending it appears as a String (using typeof), and after it sent, in the LocalCommiteHandler, Appears as Promise. – Netanel.O Sep 11 '22 at 06:38
  • See https://stackoverflow.com/questions/33438158/best-way-to-call-an-asynchronous-function-within-map and https://advancedweb.hu/how-to-use-async-functions-with-array-map-in-javascript/ – Renaud Tarnec Sep 11 '22 at 13:23

0 Answers0