Flutter Firestore更新(如果不存在则更新)

时间:2018-09-12 00:46:12

标签: flutter google-cloud-firestore

我想知道特定文档是否存在,请更新该文档,如果不能,则可以在Firestore中创建该文档。 例如,用户输入带有帖子的标签,然后看起来像这样
 Firestore.instance.collection('tags').document(tag here).updateData()。 如果该文档不存在,请问有什么方法可以创建方法,还是必须在写入之前检查是否存在?

5 个答案:

答案 0 :(得分:5)

我不知道它如何专门与Flutter配合使用(我一生中没有写过Dart行),但是其他客户端API允许在set()中使用第二个参数(或者在您的情况下为setData() ),可以创建文档(如果不存在的话),或者在已经存在的情况下合并。

有关其他语言的示例,请参见documentation。就像网络示例一样,可能只是传递{ merge: true }作为第二个参数,或者像Java一样可能使用SetOptions.merge()

答案 1 :(得分:3)

@Doug是正确的,Flutter Firestore API中有一个选项:

Firestore.instance.
  collection('tags').
  document(tag here).
  setData(data, merge: true)

来自文档:

  

setData(Map<String, dynamic> data, {bool merge: false}) → Future<void>

     

写入此DocumentReference引用的文档。如果该文档尚不存在,则会创建它。

     

如果 merge 为true,则提供的数据将被合并到现有文档中,而不是覆盖。

将其与updateData中的文档进行比较,从而明显失败。

  

updateData(Map<String, dynamic> data) → Future<void>

     

更新此DocumentReference引用的文档中的字段。

     

如果尚无文档,则更新将失败

答案 2 :(得分:2)

2021 年更新:

在文档上使用 set 并提供带有 SetOptionsmerge: true。来自docs

<块引用>

在文档上设置数据,覆盖任何现有数据。如果该文档尚不存在,则会创建该文档。

如果提供了 SetOptions,数据将合并到现有文档中而不是覆盖。

var collection = FirebaseFirestore.instance.collection('collection');
collection
    .doc('doc_id')
    .set(yourData, SetOptions(merge: true));

答案 3 :(得分:1)

看来,从2020年3月31日开始,您必须检查文档是否首先存在。 setData(data, merge: true)实际上并没有遵守merge参数。 Here is the relevant GitHub issue

我得到的行为等同于常规setData(),因此它无声地覆盖了所有现有数据。昂贵的解决方法:

final Firestore _db = Firestore.instance;
final collection = 'my_collection'
final documentId = 'my_document'
final snapShot = await _db.collection(collection).document(documentId).get();
if(snapShot.exists){
  _db.collection(collection).document(documentId).updateData(myMap);
} else {
  _db.collection(collection).document(documentId).setData(myMap);
}

答案 4 :(得分:0)

您想要的最佳做法是:

Future updateUserFirestore(
  String name,
  String dob,
  String email,
  String sex
) {

    return _getUserDetailsDocumentRef().update({
      'name': name,
      'dob': dob,
      'email': email,
      'sex': sex
    }).catchError((e) => {

      _getUserDetailsDocumentRef().set({
        'name': name,
        'dob': dob,
        'email': email,
        'sex': sex
      }, SetOptions(merge: true))
    });
}