首页 > 解决方案 > Firebase 多集合更新

问题描述

有没有办法在一个请求中更新两个文档,每个文档都在不同的集合中?

我知道您可以使用批量写入FIRWriteBatch- 这似乎仅限于任何文档更新的同一集合。尝试为两个不同集合中的文档附加更新时:

// Just for example
FIRWriteBatch *batch = FIRWriteBatch.new;

[batch updateData:@{@"posts" : @1} forDocument:[self.firebase.usersCollection documentWithPath:@"some_user_id"]];
[batch setData:@{@"test" : @"cool"} forDocument:[self.firebase.postsCollection documentWithPath:@"some_post_id"]];

[batch commitWithCompletion:^(NSError * _Nullable error) {

    NSLog(@"error: %@", error.localizedDescription);

}];

它永远不会执行 - 应用程序崩溃,我得到了这个:

Terminating app due to uncaught exception 'FIRInvalidArgumentException', reason: 
'Provided document reference is from a different Firestore instance.'

显然,该批次不喜欢多个集合中的更新。

例如,我想避免在 usersCollection 中成功设置文档posts = 1,而在postsCollection中编写新文档失败

我知道一个人写而另一个人失败是不太可能的,但如果确实发生了,我显然不想要不一致的数据。


笔记:

对于任何关心的人 - 我不知道它是否失败,但到目前为止,我在更​​新数据之前没有阅读文档就运行事务...... ‍♂️ 为 -1 API 调用干杯!

标签: objective-cfirebasegoogle-cloud-firestore

解决方案


您应该使用事务,它记录在批处理写入旁边:

Using the Cloud Firestore client libraries, you can group multiple operations into a single transaction. Transactions are useful when you want to update a field's value based on its current value, or the value of some other field. You could increment a counter by creating a transaction that reads the current value of the counter, increments it, and writes the new value to Cloud Firestore.

You are not limited to a single collection when performing a transaction. You are just obliged to read the document before you write it:

A transaction consists of any number of get() operations followed by any number of write operations such as set(), update(), or delete(). In the case of a concurrent edit, Cloud Firestore runs the entire transaction again. For example, if a transaction reads documents and another client modifies any of those documents, Cloud Firestore retries the transaction. This feature ensures that the transaction runs on up-to-date and consistent data.


推荐阅读