使用文档 ID 上传存储文件并传递 DownloadURL 时如何避免双重 Cloud Firestore 写入

Posted

技术标签:

【中文标题】使用文档 ID 上传存储文件并传递 DownloadURL 时如何避免双重 Cloud Firestore 写入【英文标题】:How to avoid double Cloud Firestore write when uploading Storage file using the document ID and passing the DownloadURL 【发布时间】:2021-03-23 07:05:40 【问题描述】:

我正在开发一个连接到 Firebase Cloud Firestore 和 Storage 的 Flutter 应用,我想在 Cloud Firestore 中创建包含 Storage 中文件的下载 URL 的文档。但是,我还需要文件名是同一 Firestore 文档的唯一 ID。现在我在创建文档后上传文件,但之后更新 Firestore 文档会花费我额外的写入时间。

我想阻止这种情况。如果我可以在 add() 函数中访问新创建的文档的 id,这样我就可以将它传递给 storageTask,它会直接在 add() 函数中返回 downloadURL。另一种选择是,如果我可以创建一个文档,获取其 ID,然后执行上传任务,然后写入所有数据,但我不确定这是否算作一次或两次写入,我也不知道如何在不设置任何数据的情况下创建文档。

我现在的大致是这样的:

CollectionReference activities = FirebaseFirestore.instance.collection('activities');
activities.add(
    'postDate': DateTime.now(),
).then((value) => _startUpload(id: value.id));

其中_startUpload 是一个将文件上传到存储的函数,并且可能会返回一个下载URL。我希望能够像这样在添加函数中访问该 URL:

CollectionReference activities = FirebaseFirestore.instance.collection('activities');
activities.add(
    'postDate': DateTime.now(),
    'downloadURL': _startUpload(id: SomehowGetThisDocuments.id)
);

【问题讨论】:

【参考方案1】:

您可以执行this section in the documentation最后一段中描述的操作:

newActivityRef = activities.document();
newActivityRef.set(
    'postDate': DateTime.now(),
    'downloadURL': _startUpload(id: newActivityRef.documentID)
);

这应该算作一次写入,因为根据文档,.document().set() 等同于 .add()

【讨论】:

以上是关于使用文档 ID 上传存储文件并传递 DownloadURL 时如何避免双重 Cloud Firestore 写入的主要内容,如果未能解决你的问题,请参考以下文章

使用从数据库传递的id将文件上载链接到表中的按钮

使用axios上传文件到阿里云对象文件存储服务器oss

使用模态存储数据并传递 $id 变量

使用 ajax 和 laravel 上传文件表单时出现问题?

将图像传递给 celery 任务

在 Angular 中从 Mongoose 下载文件