Firestore中从变量添加Map时出现空Map与Undefined问题的技术咨询
问题分析
你的核心问题出在异步操作的等待逻辑上,导致imageUrls还没被正确填充就被返回和写入Firestore了,具体有两个关键漏洞:
onUploadFiles函数里调用了Promise.all但没有await它,函数会直接返回初始的空对象{}——此时文件上传和URL获取的异步操作还没完成,imageUrls自然是空的。addChapter函数中,虽然你用了await onUploadFiles(images),但因为onUploadFiles本身没正确等待异步任务,所以then里给chapter['images']赋值的逻辑还没执行,就已经触发了Firestore的set操作,这时候chapter.images还是未定义,最终写入空Map。
解决方案
我们分两步修复代码:
1. 修复onUploadFiles函数
让函数真正等待所有上传和URL获取操作完成后,再返回填充好的imageUrls:
const onUploadFiles = async (images) => { // 用Promise.all收集所有异步任务的结果,每个任务返回[key, url]的数组 const urlEntries = await Promise.all( images.map(async (image) => { const fileRef = storage.ref(`${scanID}/${chapterNumber}/${image.name}`); await fileRef.put(image); const downloadUrl = await fileRef.getDownloadURL(); const fileName = getFileName(image.name); return [fileName, downloadUrl]; // 返回键值对数组 }) ); // 把键值对数组转成对象,比直接修改外部对象更可靠 return Object.fromEntries(urlEntries); };
2. 修复addChapter函数的执行顺序
确保在获取到imageUrls之后,再执行Firestore的写入操作,同时简化异步逻辑(尽量少混用await和then,保持代码风格一致):
const addChapter = async (images) => { try { const chapter = { id: uuidv4(), title: title, chapterNumber: chapterNumber, }; // 等待上传完成并拿到imageUrls const imageUrls = await onUploadFiles(images); // 给chapter添加images字段 chapter.images = imageUrls; // 写入Firestore await db.collection('chapters') .doc(scanID) .set( { [chapterNumber]: chapter }, { merge: true } ); console.log('Done'); } catch (error) { console.error('Something went wrong with database or upload:', error); } };
额外优化建议
- 给
getFileName加个空值判断,避免传入undefined时出错:const getFileName = (name) => { if (!name) return ''; return name.replace(/\.[^/.]+$/, ''); }; - 可以给上传过程加个loading状态,提升用户体验。
内容的提问来源于stack exchange,提问作者wick3d
相关产品推荐
相关产品推荐

