Firestore批量写入问题:从JSON文件导入仅更新1个文档
解决Firestore批量写入仅更新单个文档的问题
看起来你的批量写入逻辑里有几个关键问题导致只有最后一个文档被成功写入,我来帮你梳理并修正:
问题分析
你的代码在arr.forEach循环里,每次迭代都重新创建了一个新的batch对象并赋值给batches[commitCounter],这会把当前批次中之前添加的所有操作都覆盖掉。比如当counter从0到498时,每一次循环都会替换掉batches[commitCounter],最后这个批次里只会保留最后一个文档的set操作。另外else分支的逻辑也有漏洞,当counter超过498时,你没有把当前元素加入新创建的批次中。
修正后的代码
const db = admin.firestore(); const jsonStream = StreamArray.withParser(); let arr = []; jsonStream.on('data', ({ key, value }) => { arr.push(value); }); jsonStream.on('end', async () => { const batchSize = 500; // Firestore每个batch最多支持500个操作 let batches = []; let currentBatch = db.batch(); let operationCount = 0; arr.forEach((a, ind) => { const docRef = db.collection('Testing').doc(a.id); currentBatch.set(docRef, { ...a }); operationCount++; // 当操作数达到batch上限,或者是最后一个元素时,保存当前batch并创建新的 if (operationCount === batchSize || ind === arr.length - 1) { batches.push(currentBatch); currentBatch = db.batch(); operationCount = 0; } }); // 批量提交所有批次,使用Promise.all确保所有操作完成 try { await Promise.all(batches.map(batch => { return batch.commit().then(() => { console.count('wrote batch'); }); })); console.log('所有批次写入完成'); } catch (error) { console.error('写入失败:', error); } }); const filename = path.join(__dirname, 'mydata.json'); fs.createReadStream(filename).pipe(jsonStream.input);
关键修改点
- 避免覆盖batch对象:不再每次迭代都重新创建batch,而是维护一个当前活跃的batch,只有当操作数达到上限或者处理到最后一个元素时,才将当前batch加入批次列表并创建新的batch。
- 正确处理最后一个元素:确保即使数组长度不是batchSize的整数倍,最后剩余的操作也会被加入批次并提交。
- 使用
async/await和Promise.all:保证所有批次的提交操作都能被正确等待,同时可以捕获可能的错误,方便调试。 - 简化计数器逻辑:用
operationCount代替原来的counter和commitCounter,逻辑更清晰易懂。
这样修改后,所有文档都会被正确分组到不同的batch中,然后批量提交到Firestore,就不会出现只写入单个文档的问题了。
内容的提问来源于stack exchange,提问作者今際のアリス
相关产品推荐
相关产品推荐

