简体   繁体   English

将 Flutter 中的 FieldValue.arrayUnion 与 Cloud FireStore 一起使用

[英]Use FieldValue.arrayUnion in Flutter with Cloud FireStore

fairly new to Flutter. Flutter 相当新。 I'm trying to update an Array field that contains a List Map of type <String, dynamic>.我正在尝试更新包含 <String, dynamic> 类型的列表 Map 的数组字段。 The data structure I'm trying to achieve looks similar to the image below:我试图实现的数据结构类似于下图: 数据结构

In order to update the "notes" field for my custom object without overwriting the entire Array, I'm using FieldValue.arrayUnion with SetOptions(merge: true)like so during a call to an update function:为了在覆盖整个数组的情况下更新我的自定义 object 的“注释”字段,我在调用更新 function 期间将 FieldValue.arrayUnion 与 SetOptions(merge: true) 一起使用:

 notes: FieldValue.arrayUnion([
                                      {
                                        "date": DateTime.now(),
                                        "notes": "some test notes",
                                        "user": "some user name",
                                      }
                                    ]),

The "notes" field is part of a much larger Object and is defined as being of type nullable List of type Map<String, dynamic> like so: “notes”字段是更大的 Object 的一部分,并被定义为 Map<String, dynamic> 类型的可为空列表类型,如下所示:

List<Map<String, dynamic>>? notes;

The problem is surfacing with this error:问题出现在此错误中:

The argument type 'FieldValue' can't be assigned to the parameter type 'List<Map<String, dynamic>>?'.

and in looking at every example I've come across it looks like the function "FieldValue.arrayUnion" will only accept a String value for the field name to update.在查看我遇到的每个示例时,看起来 function "FieldValue.arrayUnion" 将只接受要更新的字段名称的字符串值。 Below is a code sample from the FireStore documentation at this link: https://cloud.google.com/firestore/docs/manage-data/add-data以下是此链接中 FireStore 文档的代码示例: https://cloud.google.com/firestore/docs/manage-data/add-data

// Atomically add a new region to the "regions" array field.
washingtonRef.update({
  "regions": FieldValue.arrayUnion(["greater_virginia"]),
});

My question is: Is there a way to pass a field from a custom object to FieldValue.arrayUnion or is the only thing it will accept a string of the field name?我的问题是:有没有办法将自定义 object 中的字段传递给 FieldValue.arrayUnion 或者是唯一可以接受字段名称字符串的方法?

As requested, I've included the full code for this problem in the hopes it can be resolved:根据要求,我已经包含了这个问题的完整代码,希望它可以得到解决:

This is the class definition with the 'notes' property with a Constructor这是 class 定义,带有 'notes' 属性和构造函数

class SchedulerEvent extends ChangeNotifier {
  String? key;
  String? title;
  String? fname;
  String? lname;
  DateTime? from;
  DateTime? to;
  List<Map<String, dynamic>>? notes;
  Color? background;
  bool? isAllDay;

  /// CTOR
  SchedulerEvent({
    this.key,
    this.title,
    this.fname,
    this.lname,
    this.from,
    this.to,
    this.notes,
    this.background,
    this.isAllDay,
  });

This is a Factory where I pull data from FireStore:这是我从 FireStore 中提取数据的工厂:

  factory SchedulerEvent.fromFireStore(DocumentSnapshot<Map<String, dynamic>> fireStoreSnapshot) {
    final data = fireStoreSnapshot.data();

    return SchedulerEvent(
      key: fireStoreSnapshot.id,
      title: data?['title'],
      fname: data?['fname'],
      lname: data?['lname'],
      from: data?['from']?.toDate(),
      to: data?['to']?.toDate(),
      notes: data?['notes'] is Iterable ? List.from(data?['notes']) : null,
      background: null,
      isAllDay: false,
    );
  }

This is where I save data back to Firestore:这是我将数据保存回 Firestore 的地方:

  Map<String, dynamic> toFireStore() {
    return {
      'title': title, 
      'fname': fname, 
      'lname': lname, 
      'from': from, 
      'to': to, 
      'notes': notes, 
      'background': background, 
      'isAllDay': isAllDay
    };
  }

This is where I create the events with (in this case) some hard-coded values for the notes:这是我使用(在这种情况下)一些硬编码的注释值创建事件的地方:

await FirebaseFirestore.instance.collection('SchedulerEventCollection').add(SchedulerEvent(
        title: '${_firstNameFormFieldController.text} ${_lastNameFormFieldController.text}',
        fname: _firstNameFormFieldController.text,
        lname: _lastNameFormFieldController.text,
        from: targetEvent.from,
        to: targetEvent.to,
        notes: [
          {
            "date": DateTime.now(),
            "notes": "some notes",
            "user": "some user",
          }
        ],
        background: null,
        isAllDay: false)
    .toFireStore());
formSubmit("Submitted the entry!");
} on Exception catch (e) {
formSubmit("Error submitting your event! ${e.toString()}");

Finally, this is where the errors start to happen when I try to update.最后,这是我尝试更新时开始发生错误的地方。 The error states错误状态

await FirebaseFirestore.instance.collection('SchedulerEventCollection').doc(targetEvent.key).set(SchedulerEvent(
        title: '${_firstNameFormFieldController.text} ${_lastNameFormFieldController.text}',
        fname: _firstNameFormFieldController.text,
        lname: _lastNameFormFieldController.text,
        from: targetEvent.from,
        to: targetEvent.to,
        notes: FieldValue.arrayUnion([
          {
            "date": DateTime.now(), 
            "notes": "some new notes", 
            "user": "some different user",
          }
        ]),
        background: null,
        isAllDay: false)
    .toFireStore(), SetOptions(merge: true));
formSubmit("Updated the Event!");
} on Exception catch (e) {
formSubmit("Error submitting your event! ${e.toString()}");

The error is below (I've tried multiple data types for "notes" but still the same problem.错误如下(我已经为“notes”尝试了多种数据类型,但仍然是同样的问题。 在此处输入图像描述

Your toFirestore is expecting notes to be of type List<Map<String, dynamic>>?您的toFirestore期望notes的类型为List<Map<String, dynamic>>? , not FieldValue.arrayUnion (and that is okay). ,而不是FieldValue.arrayUnion (没关系)。 Update your data like this:像这样更新您的数据:

try {
  final schedulerEventJson = SchedulerEvent(
    title:
        '${_firstNameFormFieldController.text} ${_lastNameFormFieldController.text}',
    fname: _firstNameFormFieldController.text,
    lname: _lastNameFormFieldController.text,
    from: targetEvent.from,
    to: targetEvent.to,
    // remove notes from here.
    background: null,
    isAllDay: false,
  ).toFireStore();

  // here I set the value of notes directly into the json
  schedulerEventJson['notes'] = FieldValue.arrayUnion([
    {
      "date": DateTime.now(),
      "notes": "some new notes4",
      "user": "some different user4",
    },
  ]);
  await FirebaseFirestore.instance
      .collection('SchedulerEventCollection')
      .doc(targetEvent.key)
      .set(schedulerEventJson, SetOptions(merge: true));
  formSubmit("Updated the Event!");
} on Exception catch (e) {
  formSubmit("Error submitting your event! ${e.toString()}");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 firebase.firestore.FieldValue.arrayUnion 不是 function - firebase.firestore.FieldValue.arrayUnion is not a function Firestore中的Cloud Functions FieldValue增量TypeError - Cloud Functions FieldValue increment TypeError in Firestore 如何在 Flutter web 应用程序中使用云 Firestore - How to use cloud firestore in Flutter web app Swift:如何在 document().setData() Firestore 数据库中使用 FieldValue.serverTimestamp()? - Swift: How to use FieldValue.serverTimestamp() in document().setData() Firestore database? flutter firestore 未在云 firestore 数据库中创建文档 - flutter firestore not creating a document in the cloud firestore database Flutter:Cloud Firestore Firestore 组件不存在 - Flutter: Cloud Firestore Firestore component is not present 有没有办法在没有 Firebase-Admin 的情况下在 Firebase Firestore JS 中使用 FieldValue.serverTimestamp() - Is there any way to use FieldValue.serverTimestamp() in Firebase Firestore JS without Firebase-Admin Flutter:Android 中的 Cloud Firestore (24.2.2) 内部错误 - Flutter: Internal error in Cloud Firestore (24.2.2) in Android 从 Cloud Firestore 使用 Flutter 获取整数 - Get an Integer with Flutter from the Cloud Firestore 使用 Flutter 从 Cloud Firestore 读取数据 - Reading data from Cloud Firestore with Flutter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM