java - 使用 Firestore 事务更新多个文档
问题描述
用例:我有多个笔记,每个笔记都绑定到一个标签。如果用户删除标签,则与该标签关联的所有注释都与默认标签相关联。所以要让它工作,我首先需要找出所有带有该标签的笔记,用默认标签的 id 替换它们的标签 id,最后删除选定的标签。所有这些都需要是原子的,因此需要 Firestore Transaction
。
出现问题是因为我想get()
通过触发query
. 既然是async
操作,交易的全部目的就消失了。我在文档中看到的示例是关于单个文档的。
FirebaseConstants.getRootRef() // db reference
.runTransaction((Transaction.Function<Void>) transaction -> {
FirebaseConstants.getNotesRef() // Notes collection reference
.whereEqualTo("labelDetails.id", "<old_label_id>")
.get()
.addOnSuccessListener(snapshots -> {
ArrayList<String> listIds = new ArrayList<>();
for (DocumentSnapshot snap : snapshots.getDocuments()) {
listIds.add(snap.getId());
}
for (String id : listIds) {
FirebaseConstants.getNotesRef()
.document(id)
.update("labelDetails.id", "<default_label_id>");
}
// Labels collection reference
FirebaseConstants.getLabelsRef().document("<old_label_id>").delete();
});
return null;
})
.addOnSuccessListener(snapshots -> {
Toast.makeText(this, "transaction success", Toast.LENGTH_SHORT).show();
})
.addOnFailureListener(e -> {
Toast.makeText(this, "transaction failed", Toast.LENGTH_SHORT).show();
});
所以,我真的很想知道如何处理这种情况。我知道,我可以get()
先匹配 id,然后在get
's中运行事务OnSuccessListener
(甚至是批量写入,因为get()
已经完成),但这并不能保证get()
和 my之间的数据一致性update()
,是吗?
因此,我想知道应该如何做到这一点。如何get
和update
多个文件使用Transaction
?
解决方案
Firestore 不支持通过查询获取文档的客户端应用程序中的事务一致性。请注意,该transaction
对象没有任何方法来执行查询。您只能执行单个文档 get() 操作。
为了获得原子更新,您必须使用提供的Transaction对象进行所有文档检索和更新。您必须先阅读文档才能编写它(但如果您阅读文档,则不必编写它)。
如果您需要处理来自查询结果的文档,您应该在事务之外执行查询并记住每个文档的 ID 以在事务中使用。如果在事务完成之前查询的结果会发生变化(例如,将添加或删除文档),那么您的事务将处理“过时”的数据。
仅当您需要阅读文档的内容以便在编写之前做出决定时,事务才有意义。在您的情况下,您实际上并没有使用每个文档的内容来决定如何处理它。在这种情况下,批量写入就足够了。
推荐阅读
- java - OSX - 从 /Library/Application Support/TestAPI 中删除文件夹
- objective-c - 使 Xcode 在向数组或字典添加可空属性时发出警告
- machine-learning - 从非结构化 pdf 分析中提取数据,我应该通过哪些工具和库?
- asp.net-core - 在 Linux 上使用 NodaTime 会丢弃使用 DateTimeOffset 转换为本地时间的时区信息
- django - 如何从 html 页面重定向以在 Django 中查看和发布数据
- verilog - Verilog 中的 Always Block 每次都会执行
- javascript - 这是使用值替换更新输入类型 = 数字字段的预期行为
- json - 如何在 Postman App 中自动加载 Postman Collection 文件
- symfony - 具有自定义 JSON 主体的 Api Platform 自定义控制器
- node.js - 无法使用 Node JS v10.14.1 os 模块中的 userInfo() 函数