Firestore存储Firebase Storage图片URL时遇undefined错误求助
解决Firestore存储图片URL数组时的undefined错误
尝试将Firebase Storage中的图片URL数组存储到Firestore时,触发错误:
Unsupported field value: undefined,Function addDoc() called with invalid data
经排查是imageUrls变量为undefined导致,尽管图片已成功上传到云存储。以下是核心问题分析及修复方案:
核心错误点
- Promise.all未获取有效结果:
map回调未返回storeImage(image)的Promise,导致Promise.all处理的是全为undefined的数组,最终imageUrls为undefined - 异步逻辑混用:同时使用
await Promise.all和.then,变量赋值逻辑混乱 - 语法错误:
addDoc调用缺少闭合括号,且未处理异步错误 - 校验未终止流程:价格、图片数量校验失败后,后续代码仍继续执行,引发无效操作
修复方案
- 给
map回调添加返回值,确保Promise.all能收集所有图片上传的Promise - 统一使用
async/await处理异步流程,避免混用.then - 修复
addDoc的语法错误,添加try/catch捕获Firestore操作错误 - 在校验失败时添加
return,终止后续代码执行 - 初始化
geolocation默认值,避免地址解析失败时存入undefined
修复后的完整代码
const onSubmit = async (e) => { e.preventDefault(); setLoading(true); // 折扣价校验:失败则终止流程 if (discountedPrice >= regularPrice) { setLoading(false); toast.error("折扣价必须低于原价"); return; } // 图片数量校验:失败则终止流程 if (images.length > 6) { setLoading(false); toast.error("最多上传6张图片"); return; } let geolocation = { lat: null, lng: null }; // 初始化默认值,避免undefined try { const response = await fetch( `https://maps.googleapis.com/maps/api/geocode/json?address=${address}&key=${process.env.React_App_YOUR_GOOGLE_API_KEY}` ); const data = await response.json(); if (data.status === "OK" && data.results.length > 0) { geolocation.lat = data.results[0].geometry.location.lat; geolocation.lng = data.results[0].geometry.location.lng; } else { setLoading(false); toast.error("地址解析失败,请检查输入"); return; } } catch (error) { setLoading(false); toast.error("地址解析失败,请检查输入"); return; } // 上传单张图片到Storage并返回下载URL const storeImage = (image) => { return new Promise((resolve, reject) => { const storage = getStorage(); const fileName = `${auth.currentUser.uid}-${image.name}-${uuidv4()}`; const storageRef = ref(storage, `images/${fileName}`); const uploadTask = uploadBytesResumable(storageRef, image); uploadTask.on( "state_changed", (snapshot) => { const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; console.log(`上传进度:${progress}%`); }, (error) => reject(error), () => { getDownloadURL(uploadTask.snapshot.ref) .then(resolve) .catch(reject); } ); }); }; try { // 批量上传图片并获取所有URL const imageUrls = await Promise.all(images.map(image => storeImage(image))); // 组装Firestore提交数据 const formDataCopy = { ...formData, imageUrls, geolocation, timestamp: serverTimestamp(), location: address }; // 清理冗余字段 delete formDataCopy.address; delete formDataCopy.images; if (!formDataCopy.offer) delete formDataCopy.discountedPrice; // 提交到Firestore const docRef = await addDoc(collection(db, "listings"), formDataCopy); setLoading(false); toast.success("发布成功"); navigate(`/category/${formDataCopy.type}/${docRef.id}`); } catch (error) { setLoading(false); console.error("发布失败:", error); toast.error("发布失败,请稍后重试"); } };
内容的提问来源于stack exchange,提问作者Papa Kow Dadson
相关产品推荐
相关产品推荐

