从事件触发功能多次更新firestore文档在几次触发后停止更新

问题描述 投票:0回答:1

我正在尝试在调整一组图像大小时更新文档,以显示进度并跟踪是否有任何图像无法转换。

我们在 dir 中几乎没有图像,其中 dir 是文档 ID。使用文档 ID,我们必须更新该文档。我们必须设置状态字段,状态包含已转换或转换失败信息的对象。 {图像:路径,处理:字符串}

看起来像 { ... 地位 : [ 文件名1:{...}, 文件名2:{...} ] }

但是当我上传 5 到 10 个图像时,它只在状态字段中设置前 4-5 个图像信息。它在将最后一个图像信息写入状态之前暂停。

虽然我尝试简单地用状态中的新数据替换旧数据,但这意味着只有单个对象会出现在此处并相应地发生更改。这在大多数情况下都有效,尽管我看到极少数情况下也失败,但大多数情况下它都有效。

async function updateDoc({filePath, metadata}) {
    const [docId, fileName] = filePath.split('/');
    
    const db = admin.firestore();
    const collectionRef = db.collection(COLLECTION_PACKS).doc(docId);
    const stickersRef = collectionRef.collection(COLLECTION_STICKERS);
  
    let attempts = 0;
    const maxAttempts = 5;

    while (attempts < maxAttempts) {
        try {
            await db.runTransaction(async (transaction) => {

                const updatedStatus = {};
                updatedStatus[fileName] = metadata;

                // Update the document with the new status and progress
                transaction.update(collectionRef, {
                    status: updatedStatus,
                });
            });
            console.log("Updated document for", filePath);
            break; // Exit the loop if successful
        } catch (error) {
            attempts++;
            console.error(`Error updating document (attempt ${attempts}):`, error);
            if (attempts >= maxAttempts) {
                throw error; // Re-throw the error after max attempts
            }
            await new Promise(resolve => setTimeout(resolve, 1000 * attempts)); // Exponential backoff
        }
    }
}

async function updateMeta({filePath, process, valid, error}){
    // console.log("updateMeta ",filePath)
    let metadata = { process, valid }
    if (error) { metadata.error = error; }
    await bucket.file(filePath).setMetadata({
        metadata: metadata
    })

    await updateDoc({ filePath, metadata})
}
firebase google-cloud-functions
1个回答
0
投票

不需要使用

db.runTransaction()
,因为您没有在更新中使用任何旧值,因此它只是添加了更多不必要的处理。

如果您的数据结构实际上是

{ ... status : { filename1:{...}, filename2:{...} } }
(请注意,我用大括号替换了方括号,我相信您的意思是对象而不是数组),那么您可以简单地更新嵌套路径,而无需使用事务。也无需重试:

// this is a docRef, not a colRef as in your example
const docRef = db.collection(COLLECTION_PACKS).doc(docId);
const update = {
  [`status.${fileName}`]: metadata,
};
await docRef.update(update);
© www.soinside.com 2019 - 2024. All rights reserved.