我想在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)
}
});
答案 0 :(得分:0)
回答了第二个问题,实际上将代码放在事务块中就可以了。我已经读过使用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)
}
});