36

I have array of objects, I want to add new object when user enter new data in the array?

Firestore.instance.collection(city).document('Attractions').updateData(
                        "data", FieldValue.arrayUnion(obj)
                      );

This shows error, How can I achieve this with flutter?

Sami Ullah
  • 429
  • 1
  • 6
  • 10

4 Answers4

47

Right Format is :

Firestore.instance.collection(city).document('Attractions').updateData({"data": FieldValue.arrayUnion(obj)});

updateData Take Map<String,dynamic> as data.

In your Code you are having , as separator between key - value instead it should be :

anmol.majhail
  • 48,256
  • 14
  • 136
  • 105
  • Thanks for you help, I tried it, But now I am getting error: – Sami Ullah Dec 07 '18 at 10:19
  • 1
    The error states: The argument type 'Map' can't be assigned to the parameter type 'List' – Sami Ullah Dec 07 '18 at 10:20
  • You need to add more Code for me to debug. Plus the new error could be of some other area of code also. – anmol.majhail Dec 07 '18 at 10:43
  • 5
    FieldValue.arrayUnion takes in a list. Use this and it should fix your error - Firestore.instance.collection(city).document('Attractions').updateData({"data": FieldValue.arrayUnion([obj])}); – sharath Feb 19 '20 at 04:48
17

@anmol.majhail 's is right, but to solve @Sami Ullah's problem, you must first make a list and add the object into the list like this:

var list = [objectBeingAdded];
Firestore.instance.collection('city').document('Attractions').updateData({"data": FieldValue.arrayUnion(list)});

Gabe
  • 5,643
  • 3
  • 26
  • 54
7

Null safe code:

Say this is the data you want to add

Map<String, dynamic> someData = {
  'foo': 1,
  'bar': true,
};
  • Add the data with unique auto-generated ID:

    var collection = FirebaseFirestore.instance.collection('collection');
    collection 
        .add(someData) 
        .then((_) => print('Added'))
        .catchError((error) => print('Add failed: $error'));
    
  • Add the data with your own ID:

    var collection = FirebaseFirestore.instance.collection('collection');
    collection 
        .doc('document_id') // <-- Document ID
        .set(someData) 
        .then((_) => print('Added'))
        .catchError((error) => print('Add failed: $error'));
    
  • Add the object to an array:

    var collection = FirebaseFirestore.instance.collection('collection');
    collection 
        .doc('document_id') // <-- Document ID
        .set({'data': FieldValue.arrayUnion(list)}) // <-- Add data
        .then((_) => print('Added'))
        .catchError((error) => print('Add failed: $error'));
    
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
2

This is a working function I built that adds new Maps to an array in my Firestore Services class. I'm using Json Serializable to annotate all my model classes. userTemplateSections is a data field in my userTemplate firestore documents. I take userTemplate as a constructor of the 'addUserTemplateSection' function to make sure I'm editing the correct document.

I also added the function I made to delete Maps from a firestore document array.

'''

Future<void> addUserTemplateSection(
      {UserTemplate userTemplate, String title, String summary}) async {
    try {
      final UserTemplateSection userTemplateSection =
          UserTemplateSection(title: title, summary: summary);
      await _firestore
          .document(FirestorePath.userTemplate(uid, userTemplate.id))
          .updateData(
        {
          'userTemplateSections':
              FieldValue.arrayUnion([userTemplateSection.toJson()])
        },
      );
    } catch (e) {
      print(e);
    }
  }

'''

'''

Future<void> deleteUserTemplateSection({
    UserTemplate userTemplate,
    UserTemplateSection userTemplateSection,
  }) async {
    try {
      await _firestore
          .document(FirestorePath.userTemplate(uid, userTemplate.id))
          .updateData(
        {
          'userTemplateSections':
              FieldValue.arrayRemove([userTemplateSection.toJson()])
        },
      );
    } catch (e) {
      print(e);
    }
  }

'''