如何在 Flutter 中使用 Firestore 删除一个集合并在同一事务中在另一个集合中创建文档

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

要删除我的应用程序中的分类广告,我有一个两步过程,其中包括:

  1. 在集合中创建新文档,同时更新另一个文档;
  2. 通过更新“deleted”: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(collectionName).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(collectionName)
        .doc(id)
        .update({
      "videoUrl": null,
      "stream": null,
    });
  }
flutter firebase google-cloud-firestore transactions
1个回答
0
投票

要删除我的应用程序中的分类广告,我有一个两步过程 包括:

  • 在集合中创建新文档,同时更新另一个文档;
  • 通过更新“deleted”:true 字段来更新广告。

我希望它成为同一事务的一部分,并且是原子的。

如果我正确理解你的问题,你希望以上 3 个操作(即创建一个新文档并更新两个文档)以原子方式完成。

这与

storeMarkVideoAndStreamToBeDeleted()
函数中的操作无关,该函数在上述过程之前被调用。

在这种情况下,您不需要使用事务,因为您不读取操作集中的任何文档,但您需要使用“批量写入”,它“以原子方式完成并可以写入多个文档”。

© www.soinside.com 2019 - 2024. All rights reserved.