如何在循环中从数据库中获取图像? React.js

How to get image from database inside loop ? React.js

我在 Firestore 数据库中有一个这样的功能集合。

{
  id: 1 
  title: Title1, 
  subtitle: Subtitle2
  image: features/feature-1.png //point folder name and image name in storage
}

但是为了在 React 中使用这张图片,我需要将这张图片转换成真正的字符串 URL

出于这个原因,Firebase 提供了类似的东西

  const getImage = async (imageName:string) => {
    const starsRef = ref(storage, imageName);
    const imageUrl = await getDownloadURL(starsRef);
    return imageUrl;
  }

所以这个函数把我的图像 (features/feature-1.png) 转换成类似的东西 https://firebasestorage.googleapis.com/v0/b/example-app.appspot.com/o/features%2Ffeature-1.png?alt=media&token=a999dfce-ee3a-4e02-95a1-6784e5afb9b9

所以我需要循环我的 Firestore 并且每次 运行 这个函数才能真正实现 URL。

  const featuresFunc = async () => {
    const featureRef = collection(db, "Features");
    const data = await getDocs(featureRef);
    let arr:any = [];
    data.forEach(async (doc:any) => {
      arr.push({...doc.data(), image: await getImage(doc.data().image)});
    })
    console.log(arr)
  }

但是它return[]数组。

这是一页的全部代码;

import { useEffect} from "react";
import {db, storage} from "../../firebase/config"
import { getDocs, collection } from "firebase/firestore";
import {ref, getDownloadURL } from 'firebase/storage'

const Features = () => {

  const getImage = async (imageName:string) => {
    const starsRef = ref(storage, imageName);
    const imageUrl = await getDownloadURL(starsRef);
    return imageUrl;
  }

  const featuresFunc = async () => {
    const featureRef = collection(db, "Features");
    const data = await getDocs(featureRef);
    let arr:any = [];
    data.forEach(async (doc:any) => {
      arr.push({...doc.data(), image: await getImage(doc.data().image)});
    })
    console.log(arr);
  }


  useEffect(() => {
    featuresFunc();
  },[])


  return null;
};

export default Features;

总结;

我想从 Firebase 商店获取我的对象并将其转换为具有真实图像的新对象 URLs。

像那样:

{title: "title1", image: features/feature-1.png, .....}
{title: "title2", image: features/feature-2.png, .....}
//into
{title: "title1", image: https://firebasestorage.googleapis.com/v0/b/example1, .....}
{title: "title2", image: https://firebasestorage.googleapis.com/v0/b/example2, .....}

发生这种情况是因为您在 forEach 循环中使用了 await。在这段代码中:

const featuresFunc = async () => {
  const featureRef = collection(db, "Features");
  const data = await getDocs(featureRef);
  let arr:any = [];
  data.forEach(async (doc:any) => {
    arr.push({...doc.data(), image: await getImage(doc.data().image)});
  })
  console.log(arr)
}

console.log(arr) 在所有 image: await getImage(doc.data().image) 完成之前运行。


我首选的处理方式是使用 Promise.all 等待所有承诺完成:

const featuresFunc = async () => {
  const featureRef = collection(db, "Features");
  const data = await getDocs(featureRef);
  let arr:any = [];
  let promises = data.docs.map((doc) => getImage(doc.data().image); // 
  let urls = await Promise.all(promises); // 
  data.forEach(async (doc:any, i) => {
    arr.push({...doc.data(), image: urls[i] }); // 
  })
  console.log(arr)
}

还有其他方法,请阅读此内容了解更多信息: