要删除分类广告在我的应用程序中,我有一个两步的过程,其中包括:
1.在集合中创建新文档,同时更新另一个文档;
1.通过更新“已删除”来更新广告:true字段。
我希望它是同一事务的一部分,是原子的。
我知道一个事务可以在get
上运行多次,而这些都必须在开始时:这让我很困惑,因为我不会有新创建的文档的多个副本。
因此,我将感谢您的帮助,告诉我如何做到这一点?
我现有的代码如下:
// Deletes the ad or throw an error if it does not exist or if an error occured
Future<void> transactionStoreDelete() async {
final fs = FirebaseFirestore.instance;
// == Move assets to to-be-deleted collections for future actual removal
// from our servers and services
// Note that if we do not succeed at moving the video assets to the
// collection, there would be a yet-to-be-delvelopped server worker that
// find unreferenced video and stream assets that will remove them from the
// cloud and our services.
try {
await storeMarkVideoAndStreamToBeDeleted();
await FirebaseFirestore.instance.runTransaction((t) async {
/// Reads the ad document
final doc = await t.get(fs.collection("ads").doc(id));
if (doc.exists) {
t.delete(doc.reference);
}
});
} catch (e) {
debugPrint(
"Could not move video assets to to-be-deleted collections: $e");
}
}
字符串
其中storeMarkVideoAndStreamToBeDeleted
如下:
/// Clean up video assets byt doing the following:
/// 1) Move the video and video stream to the to-be-deleted related collections;
/// 2) Nullify [videoUrl] and [stream] in the current ad instance;
/// 3) Update the ad in the collection.
///
Future<void> storeMarkVideoAndStreamToBeDeleted() async {
if (videoUrl != null) {
try {
// == Create record set in to be delted video
await FirebaseFirestore.instance.collection("toBeDeletedVideos").add({
...trackingInformation,
"url": videoUrl!,
});
} catch (e) {
debugPrint("Could not move the video to be deleted: $e");
}
}
if (stream != null) {
try {
// == Create record set in to be deleted stream
await FirebaseFirestore.instance.collection("toBeDeletedStreams").add({
...trackingInformation,
"streamId": stream!.id,
});
} catch (e) {
debugPrint("Could not move the stream video to be deleted: $e");
}
}
// == Now erase reference to them
return FirebaseFirestore.instance
.collection("ads")
.doc(id)
.update({
"videoUrl": null,
"stream": null,
});
}
型
[更新]在阅读评论后,试着澄清问题。
[更新2]写了收藏品的名称以供澄清。
[更新3]我想实现的伪代码中的工作流程:
t = openTheTransaction()
ad =
adsCollection.getTheAdDocumentReferenceFrom(t)
t.create(toBeDeletedVideosCollection.createDocumentWith(ad))
t.create(toBeDeletedStreamsCollection.createDocumentWith(ad))
t.update(ad, {deleted:true})
t.commit()
型
希望对你有帮助。
1条答案
按热度按时间zrfyljdw1#
更新您的问题的以下说明
您可以在Transaction中实现问题中的伪代码,如下所示:
字符串
请注意,我们使用Transaction的
set()
方法以及(CollectionReference
的)doc()
方法,而不提供任何path
以获取自动生成的docID。初始答案
要删除分类广告在我的应用程序中,我有一个两步的过程,其中包括:
我希望它是同一事务的一部分,是原子的。
如果我正确地理解了你的问题,你希望上面的3个动作(即创建一个新文档和更新两个文档)以原子方式完成。
这与
storeMarkVideoAndStreamToBeDeleted()
函数中的操作无关,该函数在上述过程之前被调用。在这种情况下,您不需要使用事务,因为您不读取操作集中的任何文档,但您需要使用批量写入,它“原子地完成并可以写入(即创建,更新和删除)多个文档”。