2

I've made a chat app and I want the user to be able to mark chatroom as favourite or mute the chatroom.

The structure of my database is like the image below

What I want is when user is trying to mute a chatroom or mark it as favourite, I only update the item that matches the chatroomId, But after a lot of searching, I found out Firebase won't allow you to update an element of an array and you can only add or remove from an array.

This is my function to mute or mark a chatroom as favourite:

static final Firestore dbReference = Firestore.instance;

static Future<void> currentUserChatroomChangeMuteOrFavouriteMethod({
    @required String chatroomId,
    @required bool muteValue,
    @required bool favouriteValue,
    @required ChatroomMuteFavouriteOption operationToBeDone,
  }) async {

 DocumentReference docRef = dbReference
        .collection("user_chatrooms")
        .document(CurrentUserDetails.id);

    DocumentSnapshot docSnapshot = await docRef.get();
    Map<String, dynamic> docData = docSnapshot.data;

    List<Map<String, dynamic>> userChatrooms =
        (docData["chatrooms"] as List<dynamic>)
            .map((chatroom) => Map<String, dynamic>.from(chatroom))
            .toList();

    for (int index = 0; index < userChatrooms.length; index++) {
      Map<String, dynamic> chatroom = userChatrooms[index];
      if (chatroom["chatroomId"] == chatroomId) {
        if (operationToBeDone == ChatroomMuteFavouriteOption.muteOperation) {
          chatroom["isMuted"] = !muteValue;
        } else {
          chatroom["isMarkedFavourite"] = !favouriteValue;
        }

        break;
      }
    }

    await docRef.updateData({"chatrooms": userChatrooms});
 }

So basically I get all the data, I update the field I want and I updateData again but this is not a good solution as I am also getting the chatrooms which I don't need.

How can I do this operation effeciently?

Thanks.

1 Answer 1

1

It's a perfectly fine solution. In order to update the contents of an array, you do have to read the document, modify the array in memory, then update the document with the new array. There's really no way to make this more efficient, other than converting your array to documents in a subcollection.

Sign up to request clarification or add additional context in comments.

4 Comments

The reason why I think it might be a bad solution is that if the user has 100 chatrooms for example, Getting and Updating all of the array in order to change a field of an item is not looking efficient in my opinion.
I don't think you have an alternative, other than what I mentioned.
Great, Thank you for the answer!
Mine is a live video call app. I decided to put all active users in an array. To avoid high firebase charges(costs per doc read). So when a single user updates the array while another user pull the same array might lead to some users missing some details. Any person with a solution here.(a better way i could use)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.