我尝试在事务中执行提取请求,但在代码执行时收到以下错误。
错误:无法修改已提交的WriteBatch。
该函数执行的步骤如下:
1.计算文档引用(取自外部源)
1.查询Firestore中可用的文档
1.验证文档是否存在
1.获取更多详细信息(延迟加载机制)
1.开始填充第一级集合
1.开始填充第二级集合
在我使用的代码下面。
await firestore.runTransaction(async (transaction) => {
// 1. Compute document references
const docRefs = computeDocRefs(colName, itemsDict);
// 2. Query the documents available in Firestore
const snapshots = await transaction.getAll(...docRefs);
snapshots.forEach(async (snapshot) => {
// 3. Verify if document exists
if (!snapshot.exists) {
console.log(snapshot.id + " does not exists");
const item = itemsDict[snapshot.id];
if (item) {
// 4. Fetch for further details
const response = await fetchData(item.detailUrl);
const detailItemsDict = prepareDetailPageData(response);
// 5. Start populating first level collection
transaction.set(snapshot.ref, {
index: item.index,
detailUrl: item.detailUrl,
title: item.title,
});
// 6. Start populating second level collection
const subColRef = colRef.doc(snapshot.id).collection(subColName);
detailItemsDict.detailItems.forEach((detailItem) => {
const subColDocRef = subColRef.doc();
transaction.set(subColDocRef, {
title: detailItem.title,
pdfUrl: detailItem.pdfUrl,
});
});
}
} else {
console.log(snapshot.id + " exists");
}
});
});
computeDocRefs
的描述如下
function computeDocRefs(colName, itemsDict) {
const identifiers = Object.keys(itemsDict);
const docRefs = identifiers.map((identifier) => {
const docId = `${colName}/${identifier}`
return firestore.doc(docId);
});
return docRefs;
}
而fetchData
则使用了axios
async function fetchData(url) {
const response = await axios(url);
if (response.status !== 200) {
throw new Error('Fetched data failed!');
}
return response;
}
prepareMainPageData
和prepareDetailPageData
是准备将它们归一化的数据的函数。
如果我注解await fetchData(item.detailUrl)
,则第一级集合及其关联的所有文档都将正确存储。
相反,对于await fetchData(item.detailUrl)
,错误发生在以下注解中:// 5. Start populating first level collection
.
操作的顺序很重要,因为如果不需要,我现在确实想进行第二次调用。
你能引导我找到正确的解决方案吗?
1条答案
按热度按时间drnojrws1#
此问题是由于
forEach
和async/await
不能很好地协同工作。例如:Using async/await with a forEach loop。现在我完全改变了我所遵循的方法,现在它工作得很顺利。
现在的代码如下所示:
非常感谢道格史蒂文森和雷诺·塔内克。