【问题标题】:Transaction does not fail, but fields are written wrongly事务没有失败,但是字段写错了
【发布时间】:2019-02-22 16:26:46
【问题描述】:

我想在 Firestore 文档中存储一个有序的图像路径列表。图像与包含位置和链接到文档的标签的元数据一起上传到存储。预期的图像数量是已知的。图像的上传几乎同时完成。

没错,我通过将图像路径列表存储为数组来做到这一点。 简而言之:上传图像,使用事务读取文档,更改数组并再次保存。事务永远不会失败,但有时一个数组项会在另一张图片上传后再次消失。

我的两个问题是:数组是 NoSql 数据库中解决这个问题的最佳结构吗?尽管有交易,为什么数组项会消失?

export const addImageToTag = functions.storage.object().onFinalize(async (object) => {
    try {
        const tag = object.metadata.Tag;
        const position = object.metadata.Position;

        const tagRef = db.collection(COLLECTION_TAGS).doc(tag)
        const tagSnapshot = await db.runTransaction(t => t.get(tagRef));

        const images = tagSnapshot.data().images;
        images[position] = object.name;

        let uploadCount = 0;
        for (let i = 0; i < tagSnapshot.data().imageCount; i++) {
            if (images[i].length > 0) {
                uploadCount++;
            } else {
                break;
            }
        }

        let state;
        if (tagSnapshot.data().imageCount === uploadCount) {
            state = STATE_ACTIVE;
        } else {
            state = STATE_UPLOADING;
        }

        await tagSnapshot.ref.update({
            images: images,
            state: state
        });

        console.log('Image ', position, ' of tag ', tag, 'added')
    } catch (error) {
        console.error('Call failed: ', error)
    }
});

【问题讨论】:

    标签: node.js typescript firebase google-cloud-firestore google-cloud-functions


    【解决方案1】:

    回答了第二个问题,实际上将代码放入事务块中就可以了。我读过使用tagSnapshot.ref 引用标签文档就足够了,这是错误的。

    export const addImageToTag = functions.storage.object().onFinalize(async (object) => {
        try {
            const tag = object.metadata.Tag;
            const position = object.metadata.Position;
            const tagRef = db.collection(COLLECTION_TAGS).doc(tag)
    
            await db.runTransaction(async transaction => {
                const tagSnapshot = await transaction.get(tagRef)
    
                const images = tagSnapshot.data().images;
                images[position] = object.name;
    
                let uploadCount = 0;
                for (let i = 0; i < tagSnapshot.data().imageCount; i++) {
                    if (images[i].length > 0) {
                        uploadCount++;
                    } else {
                        break;
                    }
                }
    
                let state;
                if (tagSnapshot.data().imageCount === uploadCount) {
                    state = STATE_ACTIVE;
                } else {
                    state = STATE_UPLOADING;
                }
    
                transaction.update(tagRef, {
                    images: images,
                    state: state
                });
    
                if (state === STATE_ACTIVE) {
                    console.log('All images of tag ', tag, ' were succesfully added')
                }
                });
        } catch (error) {
            console.error('Call failed: ', error)
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2014-05-07
      • 1970-01-01
      • 1970-01-01
      • 2020-06-28
      • 2013-02-22
      • 2021-03-26
      • 1970-01-01
      • 1970-01-01
      • 2021-01-05
      相关资源
      最近更新 更多