Estoy tratando de usar async/await para obtener imágenes del almacenamiento de firebase, y esta es mi función:
import { ref as sRef, getDownloadURL } from "firebase/storage"; ... async getCharacterIconUrl(character) { return await getDownloadURL(sRef(storage, `characters/${character}/icon`)); }
Y luego, uso esta función aquí:
import { ref, child, get } from "firebase/database"; ... async componentDidMount() { const dbRef = ref(db); let snapshot = await get(child(dbRef, "en/characters")); if (snapshot.exists()) { let characters = Object.keys(snapshot.val()).map((key) => { return { _id: key, img: this.getCharacterIconUrl(key), ...snapshot.val()[key], }; }); this.setState({ characters: characters }); } else { console.log("No data available"); } }
El problema que tengo es que img
dentro de los characters
nunca se resuelve.
¿Como puedo resolver esto?
Su función getCharacterIconUrl
es async
, por lo que debe esperarla .
Prueba esto...
const characters = await Promise.all( Object.entries(snapshot.val()).map(async ([_id, val]) => ({ _id, img: await this.getCharacterIconUrl(_id), ...val, })) ) this.setState({ characters });
Tenga en cuenta que la devolución de llamada .map()
también es async
. También estoy usando Object.entries()
ya que quieres claves y valores.
Dado que getCharacterIconUrl
es una función asíncrona, devuelve una promesa. Por lo tanto, su campo img
es una promesa; combinado con map()
, eso se convierte en una matriz de promesas. Por lo tanto, podemos usar Promise.all()
para resolverlos.
async componentDidMount() { const dbRef = ref(db); let snapshot = await get(child(dbRef, "en/characters")); if (snapshot.exists()) { let characterPromises = Object.keys(snapshot.val()).map(async (key) => { return { _id: key, img: await this.getCharacterIconUrl(key), ...snapshot.val()[key], }; }); this.setState({ characters: await Promise.all(characterPromises)}); } else { console.log("No data available"); } }