Search code examples
firebaseflutterdartgoogle-cloud-firestoreflutter-web

How can I update map data that's in a array in firebase? (Flutter)


I'm using flutter web and firebase for a project and got stuck on a problem. I'm trying to update a map in an array in firestore.

using this:

var val = [];
    val.add({'groupUID': groupUID, 'inviteStatus': status});
    var userInviteUID;
    await users
        .document(uid)
        .get()
        .then((value) => userInviteUID = value.data['inviteUID']);
    await invites
        .document(userInviteUID)
        .updateData({'invites': FieldValue.arrayUnion(val)});

I got this result: firestore structure

What I want to do is just change the 1 to a 2 in the map. I thought that it would update since its the same value but it just adds it to the array.

I looked around on stack and saw some ways to do it like copying the entire array and changing it where I need to, then adding it back.

But I wanted to know if there was a way to avoid that by adding some modifications to my code. Also let me know if there's a better structure I should use. Appreciate the help!

UPDATE:

var ref = invites.document(userData.inviteUID);
    ref.get().then((value) async {
      var invitesList = value.data['invites'];

      switch (status) {
        case 1:
          break;
        case 2:
          var index;
          invitesList.asMap().forEach((key, value) {
            if (value['groupUID'] == groupUID) index = key;
          });
          invitesList.removeAt(index);
          await invites
              .document(userData.inviteUID)
              .updateData({'invites': FieldValue.arrayUnion(invitesList)});
          break;
        default:
      }

So I looked at some print statements and seen that the elements with the matching group uid is removed, but looking at firebase, the array isn't overwritten anything...any ideas?

FINAL UPDATE:

var ref = invites.document(userData.inviteUID);
        ref.get().then((value) async {
          var invitesList = value.data['invites'];
    
          switch (status) {
            case 1:
              break;
            case 2:
              var index;
              invitesList.asMap().forEach((key, value) {
                if (value['groupUID'] == groupUID) index = key;
              });
              invitesList.removeAt(index);
              await invites
                  .document(userData.inviteUID)
                  .setData({'invites': FieldValue.arrayUnion(invitesList)});
              break;
            default:
          }

Fixed it by changing updateData to setData.


Solution

  • I looked around on stack and saw some ways to do it like copying the entire array and changing it where I need to, then adding it back.

    That's exactly how you are supposed to modify the contents of arrays in Firestore documents. Firestore doesn't support updating array elements by index.