Martin Palmer
Martin Palmer

Reputation: 97

Flutter FireStore Create, Read and Update Array with a Map Object

Fairly new to Flutter and FireStore, I'm having trouble finding examples or explanations on how to add Maps to an Array (specifically, Creating the initial Array with a Map, then Reading then Adding more Maps to the collection of the Notes Array).

I have an Event Class for scheduling events and that is working very well. What I'm trying to add is a "Notes" field that would allow an some Administrator to add Notes on one day then come back and add to that Event another set of notes as things change. I don't want to "overwrite" the previous Notes, just keep adding more Notes to the Array of notes.

Specific questions:

  1. How do I Create the "Array" when adding the entry into FireStore using Flutter?
  2. How do I Read the data in the "Array" when it's coming back as a set of "Map fields" in Flutter?
  3. How do I just Add to the Array with a new Note? (I think this needs FieldValue.arrayUnion([someMap]) but I'm not certain as this appears to avoid any overwriting.

The page section here shows writing it out but little else: https://firebase.google.com/docs/firestore/manage-data/add-data#data_types

Below is an example of the FireStore structure I'm trying to create. enter image description here

Has anyone done this before and do you have some direction you can provide? The Firebase documentation in this space is thin...

Upvotes: 3

Views: 1881

Answers (1)

Peter Obiechina
Peter Obiechina

Reputation: 2835

  1. To create an new document with array in firestore:
FirebaseFirestore.instance.collection('path/to/collection').add(
  { 'notesArray': [
    {'date': 'sometime', 'notes': 'somenotes', 'user': 'someuser'}
  ]},
  SetOptions(merge: true),
);
// or
FirebaseFirestore.instance.collection('path/to/collection').add(
  { 'notesArray': []}, // for an empty array
  SetOptions(merge: true),
);
  1. To read the data:
FirebaseFirestore.instance.doc('company').get().then((value) {
  final doc = value.data()!;
  print(doc['lname']); // should print Gethsemane
  print(doc['notesArray'] as List); // should print notes array
  final notes = doc['notesArray'] as List;
  for (final note in notes) {
    print(note['date']);
    print(note['notes']);
    print(note['user']);
  }
  // or
  for (int i = 0; i < notes.length; i++) {
    print(notes[i]['date']);
  }
});
  1. Add new data to notes array. Simply use FieldValue.arrayUnion.

E.g

FirebaseFirestore.instance.doc('path/to/doc').set(
  {
    'notesArray': FieldValue.arrayUnion([
      {'date': 'sometime', 'notes': 'somenotes', 'user': 'someuser'}
    ]),
  },
  SetOptions(merge: true),
);
// I used set method along with setOptions in order not to 
// override other fields (e.g modifiedBy field)

Keep in mind that if your array is going to be very large, it is better to store the notes as a subcollection.

##EDIT##

If you want to update a nested array, you can use the dot notation.

class SchedulerEvents {
  final List<Map<String, dynamic>>? notes;
  SchedulerEvents({required this.notes});
}

// lets assume we have data like this that we want to update
final data = SchedulerEvents(
  notes: [
    {'date': 'sometime', 'notes': 'somenotes', 'user': 'someuser'},
  ],
);
FirebaseFirestore.instance.doc('path/to/doc').set(
  {
    'schedulerEvents.notes': FieldValue.arrayUnion([data.notes![0]]),
    // or
    'schedulerEvents.notes': FieldValue.arrayUnion(data.notes![0]),
    // 'schedulerEvents.lname: 'test', // to update other fields
  },
  SetOptions(merge: true),
);
// we used dot notation to update fields here.

Upvotes: 4

Related Questions