Skip to content

[BUG] ParticipantsRemovedEvent has empty participantsRemoved property #1984

@shuchenku

Description

@shuchenku

Describe the bug
When shareHistoryTime is null for an participant, ParticipantsRemovedEvent converted from ChatEvent payload will have an empty participantsRemoved array.

Exception or Stack Trace
No stack trace but below are the toString()s for ParticipantsRemovedEvent when participantsRemovedJsonString has an null shareHistoryTime versus when it has a valid time.
NULL shareHistoryTime:

{"participantsRemoved":[],
"participantsRemovedJsonString":"[{\"shareHistoryTime\":null,
                                "displayName\":\"Shu2 QA2\",
                                "participantId\":\"8:acs:ae06a922-4b87-412a-98d5-7e1c5b55edc6_00000025-0c2b-0ce2-1252-573a0d005cab\",
                                "memberMetaData\":\"null\"}]",
"removedBy":{"communicationIdentifier":{"id":"8:acs:ae06a922-4b87-412a-98d5-7e1c5b55edc6_00000025-0c2b-0ce2-1252-573a0d005cab","rawId":"8:acs:ae06a922-4b87-412a-98d5-7e1c5b55edc6_00000025-0c2b-0ce2-1252-573a0d005cab"},"displayName":"Shu2 QA2"},
"removedByJsonString":"{\"displayName\":\"Shu2 QA2\",
                        "participantId\":\"8:acs:ae06a922-4b87-412a-98d5-7e1c5b55edc6_00000025-0c2b-0ce2-1252-573a0d005cab\",
                        "memberMetaData\":null}",
"removedOn":{"dateTime":{"date":{"day":10,"month":9,"year":2025},"time":{"hour":18,"minute":57,"nano":933451000,"second":38}},
"offset":{"totalSeconds":0}},
"version":"1757530658853",
"groupId":"",
"threadId":"19:acsV2_e814cc46a24f4fb4b0c118167746827d@thread.v2"
}

Valid shareHistoryTime

{"participantsRemoved":[{"communicationIdentifier":{"id":"8:acs:ae06a922-4b87-412a-98d5-7e1c5b55edc6_00000025-0c2b-0ce2-1252-573a0d005cab","rawId":"8:acs:ae06a922-4b87-412a-98d5-7e1c5b55edc6_00000025-0c2b-0ce2-1252-573a0d005cab"},"displayName":"Shu2 QA2","shareHistoryTime":{"dateTime":{"date":{"day":10,"month":9,"year":2025},"time":{"hour":19,"minute":10,"nano":400000000,"second":1}},"offset":{"totalSeconds":0}}}],
"participantsRemovedJsonString":"[{\"shareHistoryTime\":1757531401400,
                                "displayName\":\"Shu2 QA2\",
                                "participantId\":\"8:acs:ae06a922-4b87-412a-98d5-7e1c5b55edc6_00000025-0c2b-0ce2-1252-573a0d005cab\",
                                "memberMetaData\":\"null\"}]",
"removedBy":{"communicationIdentifier":{"id":"8:acs:ae06a922-4b87-412a-98d5-7e1c5b55edc6_00000025-0c2b-0ce2-1252-573a0d005cab","rawId":"8:acs:ae06a922-4b87-412a-98d5-7e1c5b55edc6_00000025-0c2b-0ce2-1252-573a0d005cab"},"displayName":"Shu2 QA2"},
"removedByJsonString":"{\"displayName\":\"Shu2 QA2\",
                        "participantId\":\"8:acs:ae06a922-4b87-412a-98d5-7e1c5b55edc6_00000025-0c2b-0ce2-1252-573a0d005cab\",
                        "memberMetaData\":null}",
"removedOn":{"dateTime":{"date":{"day":10,"month":9,"year":2025},"time":{"hour":19,"minute":10,"nano":922730500,"second":12}},
"offset":{"totalSeconds":0}},
"version":"1757531412859",
"groupId":"",
"threadId":"19:acsV2_444db53cebd24019a5e81967afaec64a@thread.v2"}

To Reproduce
Prereq: Have Users A, B, C, etc. as valid ACS users; all users subscribing to ACS realtime events on Android clients.
Steps to reproduce the behavior:

  1. As User A, use the 'chat/threads' ACS endpoint to create a group chat that contains users A, B, and C.
  2. As User B, call 'chat/threads/{threadId}/participants/:remove' with their ACS id to leave the chat.
  3. On User A's device, observe the PARTICIPANTS_REMOVED event: participantsRemovedJsonString contains removed participant info for User B
  4. When converted the event data to an ParticipantsRemovedEvent instance, participantsRemoved array is empty.

Code Snippet
ChatAsyncClient chatAsyncClient = MessagesClient.getChatAsyncClient();

    Log.i(TAG, "Starting real time notification for participants removed");
    chatAsyncClient.addEventHandler(ChatEventType.PARTICIPANTS_REMOVED,
            (ChatEvent payload) -> handler.post(() -> {
                ParticipantsRemovedEvent removeParticipantsEvent = (ParticipantsRemovedEvent) payload;

                List<ChatParticipant> participantsRemoved = removeParticipantsEvent.getParticipantsRemoved();
                if (participantsRemoved != null && !participantsRemoved.isEmpty()) {
                    try {
                        ChatParticipant chatParticipant = participantsRemoved.get(0);
                        CommunicationIdentifier identifier = chatParticipant.getCommunicationIdentifier();
                        String participantAcsId = ((CommunicationUserIdentifier) identifier).getId();

                        ChatParticipant removedBy = removeParticipantsEvent.getRemovedBy();
                        String removedByAcsId = ((CommunicationUserIdentifier) removedBy
                                .getCommunicationIdentifier()).getId();

                        HashMap<String, String> participantPayload = new HashMap<>();

                        participantPayload.put("eventType", ChatEventType.PARTICIPANTS_REMOVED.toString());
                        participantPayload.put("threadId", removeParticipantsEvent.getChatThreadId());
                        participantPayload.put("removedOn", removeParticipantsEvent.getRemovedOn().toString());
                        participantPayload.put("actionByAcsId", removedByAcsId);
                        participantPayload.put("participantsRemoved", new Gson().toJson(participantsRemoved));
                        event.success(participantPayload);
                    } catch (Exception e) {
                        Log.e(TAG, "Error handling participants removed event: " + e.getMessage());
                    }
                } else {
                    Log.e(TAG, "Participants removed list is null or empty");
                }
            })
    );

Expected behavior
The ParticipantsRemovedEvent converted from the ChatEvent payload should have the removed participant data in participantsRemoved even when shareHistoryTime is empty.

Screenshots
If applicable, add screenshots to help explain your problem.

Setup (please complete the following information):

  • OS: Android 16
  • IDE : VSCode?
  • azure-communication-chat:2.0.2/azure-communication-common:1.0.2

Additional context
Add any other context about the problem here.

Information Checklist
Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report

  • Bug Description Added
  • Repro Steps Added
  • Setup information Added

Metadata

Metadata

Assignees

No one assigned

    Labels

    customer-reportedIssues that are reported by GitHub users external to the Azure organization.needs-triageWorkflow: This is a new issue that needs to be triaged to the appropriate team.questionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions