'How to remove an item from repeated list in Android proto DataStore?

Here is the proto file with the definition for a list of strings.

message MyMessages {
    repeated string message = 1;
}

Here is the function for removing a message from the repeated message list.

suspend fun removeMsg(msg : String) {
    myMessagesStore.updateData { myMessages ->
        val existingMessages = myMessages.toBuilder().messageList;
        if (existingMessages.contains(msg)) {
            existingMessages.remove(msg)
            myMessages.toBuilder().clear().addAllMessage(existingMessages).build()
        } else {
            myMessages
        }
    }
}

When the above code runs, it crashed on existingMessages.remove(msg) with the error:

java.lang.UnsupportedOperationException
        at java.util.Collections$UnmodifiableCollection.remove

existingMessages is a MutableList which contains the remove function, why is this crashing on this and what's the proper way to remove an item from a repeated list item in proto DataStore?

Updates: existingMessages is

/**
 * <code>repeated string message = 1;</code>
 * @return A list containing the message.
 */
@java.lang.Override
public java.util.List<java.lang.String>
    getMessageList() {
  return java.util.Collections.unmodifiableList(
      instance.getMessageList());
}

It looks like the generated class from proto is making the repeated list unmodfiableList. Then my question is why there isn't a myMessages.toBuilder().removeMessage(newMessage) function from the generated class similar to the addMessage function such as this:

myMessages.toBuilder().addMessage(newMessage)


Solution 1:[1]

Could you please post the exact data type of existingMessages.

I am not an expert in proto DataStore, so please correct me incase I am wrong. As per the exception message, there could be few main reason behind the crash:

  1. The existingMessages is immutable list. As per the exception, we can see that the name of the collection is java.util.Collections$UnmodifiableCollection.
  2. The existingMessages is a custom mutable list, which haven't implemented the #remove function.

To fix this, you can choose one of the following approach based on your guidelines:

  1. Update the type of messageList in Builder class as MutableList for other external classes.
  2. In case you are using custom implementation of list and the #remove is not implemented, please implement it.
  3. In case you can't change the return type of messageList, simply use #filter method to copy and skip the required message as follow:
existingMessages.filter { it != msg }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ashok