You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Formik场景下如何正确上传图片URL数组到Firestore

问题根因

两个核心问题导致图片链接未正常写入Firestore:

  1. 异步逻辑未正确等待:getLinks函数循环执行时,没有等待uploadBytes和getDownloadURL的Promise执行完成就提前返回空数组。控制台打印对象时能看到链接是浏览器的延迟求值特性导致的——日志输出的是对象引用,你手动点击展开日志时异步push操作已经执行完成,但实际运行addDoc时,传入的imageArray还是空数组。
  2. 原始文件未存储:复现代码中的selectMultipleFiles方法只保存了本地预览用的blob地址,没有存储上传需要的原始File对象,getLinks根本拿不到要上传的文件。
  3. 提示逻辑错误:原代码把成功提示放在finally回调中,无论上传成功还是失败都会触发成功提示,不符合预期。
修复方案

按以下步骤调整代码即可:

  • 新增state存储待上传的原始文件对象
  • 修正文件选择逻辑,同时保存预览地址和原始File
  • 重写getLinks方法,用Promise.all等待所有文件上传、链接获取操作全部完成后再返回结果
  • 调整Promise链结构,把成功提示移到上传完成的回调中,错误提示保留在catch分支

修复后核心代码

首先调整状态定义:

// 新增rawFiles存储原始上传文件
const [images, setImages] = useState([])
const [rawFiles, setRawFiles] = useState([])

修正文件选择方法:

const selectMultipleFiles = (e) => {
  const selectedFiles = Array.from(e.target.files);
  const previewUrls = selectedFiles.map(file => URL.createObjectURL(file));
  setImages(previewUrls);
  // 保存原始文件供上传使用
  setRawFiles(selectedFiles);
};

重写getLinks函数,正确处理异步流程:

const getLinks = async () => {
  // 批量生成上传+取链接的异步任务
  const uploadTasks = rawFiles.map(async (file) => {
    // 建议加时间戳/随机前缀避免同名文件覆盖,这里保留原路径逻辑
    const storageRef = ref(storage, `/houses/${Date.now()}_${file.name}`);
    const snapshot = await uploadBytes(storageRef, file);
    return getDownloadURL(snapshot.ref);
  });
  // 等待所有任务完成后返回完整链接数组
  return Promise.all(uploadTasks);
};

修正onSubmit逻辑:

onSubmit: async (values) => {
  getLinks()
    .then((imageArray) => {
      const newVals = { ...values, imageList: imageArray };
      return newVals;
    })
    .then(async (newValues) => {
      console.log(newValues);
      await addDoc(collection(db, "properties"), newValues);
      // 上传成功后再弹成功提示
      setSnackAlert({
        type: "success",
        message: "You provided values!! Congrats!",
      });
      handleOpen();
    })
    .catch((err) => {
      console.error(err);
      setSnackAlert({
        type: "error",
        message: "There was an error handling your request",
      });
      handleOpen();
    });
}
验证方法

修复后可以在addDoc调用前打印newValues.imageList.length,如果输出值和你选择的图片数量一致,说明异步逻辑正常,此时写入Firestore的文档就会携带完整的图片链接数组。


内容的提问来源于stack exchange,提问作者Brady Bott

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 19:30:50