0

I'm querying a collection and get data in a Map structure, like so-

eventData : [{
   eventUID: rQigoeThdP0thE9oChld,
   eventLocation: Bldg-4,
   eventName: Test Prod 0217,
   eventStatus: Complete,
   eventContacts: [{                    
   contactName: Anna Leochal,
   contactTitle: Station Dir,
   contactUID: L2z9Jhr3i49YVBLzA4ta
   }, {                 
   contactName: Eleonore Hendricks,
   contactTitle: Station Manager,
   contactUID: ArklRd6Ggivcvi9OMHvj
   }, {                 
   contactName: Tom Warner,
   contactTitle: Station Asst Mgr,
   contactUID: 0bfGw5kaYgseKTxshbMW
   }
  ],
   eventDateModified: Timestamp(seconds = 1676668006, nanoseconds = 962000000),
   eventDateCreated: Timestamp(seconds = 1676667859, nanoseconds = 944000000)
  }
]

What I would like to do is remove data from the eventContacts section identified by a passed parameter myContactUID. ie. passing in myContactUID = "0bfGw5kaYgseKTxshbMW" would remove Tom Warner's data from eventConcats.

This is where I'm getting hung up. I need to remove the entire object that's associated with Tom's contactUID (contactName,contactTitle,contactUID) from eventContacts

If I cast eventContacts as a List, ie. final List myEventContacts = document.get(FieldPath(const ["eventContacts"]))! as List; I get-

myEventContacts: [{                 
   contactName: Anna Leochal,
   contactTitle: Station Dir,
   contactUID: L2z9Jhr3i49YVBLzA4ta
   }, {                 
   contactName: Eleonore Hendricks,
   contactTitle: Station Manager,
   contactUID: ArklRd6Ggivcvi9OMHvj
   }, {                 
   contactName: Tom Warner,
   contactTitle: Station Asst Mgr,
   contactUID: 0bfGw5kaYgseKTxshbMW
   }
  ]

I've tried permutations of-

var eventUpdate = {};
eventUpdate[ eventConcats.contactUID : {[myContactUID]: firebase.firestore.FieldValue.delete();}];
db.collection('events').doc('$myEventDocID').set(eventUpdate);

As so-

      WriteBatch myEventDocBatch = FirebaseFirestore.instance.batch();
  db
      .collection('events')
      .where('eventUID', isEqualTo: myEventUID)
      .get()
      .then((querySnapshot) {
    var qsEventsLen = querySnapshot.docs.length;
    var qsEventsSize = querySnapshot.size;
    print('qsEventsLen: $qsEventsLen    ');
    print('qsEventsSize: $qsEventsSize    ');

    querySnapshot.docs.forEach((document) {
      // do something with myBatch
      // myEventDocBatch.delete(document.reference);

      var myEventDocID = document.id; // i.e. 6eWyqjfEdG4ZJlepoHSf
      print('myEventDocID: $myEventDocID');

      var myEventUID = document.get(FieldPath(const ["eventUID"]))!
          as String; // i.e. rQigoeThdP0thE9oChld
      print('myEventUID: $myEventUID');

      final eventData = document.data();
      print("eventData: ${document.data()}");

      final List myEventContacts =
          document.get(FieldPath(const ["eventContacts"]))! as List;
      print("myEventContacts: ${myEventContacts}");

      var eventUpdate = {};
      eventUpdate[ eventConcats.contactUID : {[myContactUID]: firebase.firestore.FieldValue.delete();}];
      db.collection('events').doc('$myEventDocID').set(eventUpdate);

    });
    return myEventDocBatch.commit();
  });
  print('End: Get Event Doc');

To no avail. None of what I've researched seems to help in this case. I'm just more confused.

Any ideas would be most welcome

previous research: Cloud Firestore: Update fields in nested objects with dynamic key

Firebase firestore nested query

Query map object data in dart/flutter based on key value

How to delete object from array in firestore

Chris G.
  • 329
  • 4
  • 17

1 Answers1

0

I figured it out. Had to convert the myEventContacts List to a Map and iterate over the values then remove the found item at the index. I don't think this is the most efficient route to take so, if you have an idea of how to streamline this, I'd love to see it! Otherwise, I hope this helps someone else.

    querySnapshot.docs.forEach((document) async {

      var myEventDocID = document.id; // i.e. 6eWyqjfEdG4ZJlepoHSf
       print('myEventDocID: $myEventDocID');

      var myEventUID = document.get(FieldPath(const ["eventUID"]))!
          as String; // i.e. rQigoeThdP0thE9oChld
       print('myEventUID: $myEventUID');

      final eventData = document.data();
       print("eventData: ${document.data()}");

      final List myEventContacts =
          document.get(FieldPath(const ["eventContacts"]))! as List;
       print("myEventContacts: ${myEventContacts}");
      
      // Convert myEventContacts to a Map
      final mapMyContact = myEventContacts.asMap();
       print("z mapMyContact: ${mapMyContact}");

      final lenMapMyContact = mapMyContact.length;
       print("lenMapMyContact: $lenMapMyContact");

      // remove item from myEventContacts Map
      int idxContactUID = 99999999;
      for (int i = 0; i < mapMyContact.length; i++) {
        if (mapMyContact[i].toString().contains('$myContactUID')) {
          idxContactUID = i;
           print("- Found contactUID [$myContactUID] in mapMyContact at index $idxContactUID");

          myEventContacts.removeAt(idxContactUID);
           print("- myEventContacts: ${myEventContacts}");
          final docRef = db.collection('events').doc(myEventDocID);
          await docRef.update({'eventContacts': myEventContacts});
        }
      }

      if (idxContactUID == 99999999) {
        print("contactUID [$myContactUID] NOT FOUND in mapMyContact");
      }
    }
Chris G.
  • 329
  • 4
  • 17