> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-angular-v5-docs-update.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Reactions

> Add, remove, and fetch message reactions in real-time using the CometChat Android SDK. Includes listener events and helper methods for updating UI.

Reactions let users respond to messages with emoji. You can add or remove reactions, fetch all reactions on a message, listen for reaction events in real time, and update your UI when reactions change.

## Add a Reaction

Users can add a reaction to a message by calling `addReaction` with the message ID and the reaction emoji. On success, returns a [`BaseMessage`](/sdk/reference/messages#basemessage) object with updated reactions.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    int messageId = 1;
    String emoji = "😊";

    CometChat.addReaction(messageId, emoji, new CometChat.CallbackListener<BaseMessage>() {
      @Override
      public void onSuccess(BaseMessage message) {
          Log.e(TAG, "Reaction added: " + message.getReactions());
      }

      @Override
      public void onError(CometChatException e) {
          Log.e(TAG, "Failed to add reaction: " + e.getMessage());
      }
    });
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val messageId = 1
    val emoji = "😊"

    CometChat.addReaction(messageId, emoji, object : CometChat.CallbackListener<BaseMessage>() {
      override fun onSuccess(message: BaseMessage?) {
          Log.e(TAG, "Reaction added: ${message.reactions}")
      }

      override fun onError(e: CometChatException?) {
          Log.e(TAG, "Failed to add reaction: ${e?.message}")
      }
    })
    ```
  </Tab>
</Tabs>

<Info>
  You can react on Text, Media and Custom messages. For more details on message types, see [Message Structure & Hierarchy](/sdk/android/message-structure-and-hierarchy).
</Info>

## Remove a Reaction

Removing a reaction from a message can be done using the `removeReaction` method.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    int messageId = 1;
    String emoji = "😊";

    CometChat.removeReaction(messageId, emoji, new CometChat.CallbackListener<BaseMessage>() {
      @Override
      public void onSuccess(BaseMessage message) {
          Log.e(TAG, "Reaction removed: " + message.getReactions());
      }

      @Override
      public void onError(CometChatException e) {
          Log.e(TAG, "Failed to remove reaction: " + e.getMessage());
      }
    });
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val messageId = 1
    val emoji = "😊"

    CometChat.removeReaction(messageId, emoji, object : CometChat.CallbackListener<BaseMessage>() {
      override fun onSuccess(message: BaseMessage?) {
          Log.e(TAG, "Reaction removed: ${message.reactions}")
      }

      override fun onError(e: CometChatException?) {
          Log.e(TAG, "Failed to remove reaction: ${e?.message}")
      }
    })
    ```
  </Tab>
</Tabs>

## Fetch Reactions for a Message

To get all reactions for a specific message, first create a `ReactionRequest` using `ReactionRequestBuilder`. You can specify the number of reactions to fetch with `setLimit` with max limit 20. For this, you will require the ID of the message. This ID needs to be passed to the `setMessageId()` method of the builder class. The `setReaction()` will allow you to fetch details for specific reaction or emoji.

| Setting                     | Description                                                                                                                                                                                                          |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `setMessageId(int value)`   | Specifies the unique identifier of the message for which you want to fetch reactions. This parameter is mandatory as it tells the SDK which message's reactions are being requested.                                 |
| `setReaction(String value)` | Filters the reactions fetched by the specified reaction type (e.g., "😊", "😂", "👍"). When set, this method will cause the ReactionRequest to only retrieve details of the provided reaction for the given message. |

### Fetch Next

The `fetchNext()` method fetches the next set of reactions for the message.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    int limit = 30;
    int messageId = 1;

    ReactionsRequest reactionRequest = new ReactionsRequest.ReactionsRequestBuilder()
          .setLimit(30)
          .setMessageId(1)
          .build();

    reactionRequest.fetchNext(new CometChat.CallbackListener<List<Reaction>>() {
      @Override
      public void onSuccess(List<Reaction> reactions) {
          Log.e(TAG, "Total Reactions: " + reactions.size());
          for (Reaction reaction : reactions) {
              Log.e(TAG, "Reaction: " + reaction.getReaction());
          }
      }

      @Override
      public void onError(CometChatException e) {
          Log.e(TAG, "Reaction fetch error: " + e.getMessage());
      }
    });
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val limit = 30
    val messageId = 1

    val reactionRequest = ReactionsRequest.ReactionsRequestBuilder()
          .setLimit(limit)
          .setMessageId(messageId)
          .build()

    reactionRequest.fetchNext(object : CometChat.CallbackListener<List<Reaction>>() {
      override fun onSuccess(reactions: List<Reaction>?) {
          Log.e(TAG, "Total Reactions: ${reactions?.size}")
          reactions?.forEach { reaction ->
              Log.e(TAG, "Reaction: ${reaction.reaction}")
          }
      }

      override fun onError(e: CometChatException?) {
          Log.e(TAG, "Reaction fetch error: ${e?.message}")
      }
    })
    ```
  </Tab>
</Tabs>

### Fetch Previous

The `fetchPrevious()` method fetches the previous set of reactions for the message.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    int limit = 30;
    int messageId = 1;

    ReactionsRequest reactionRequest = new ReactionsRequest.ReactionsRequestBuilder()
          .setLimit(30)
          .setMessageId(1)
          .build();

    reactionRequest.fetchPrevious(new CometChat.CallbackListener<List<Reaction>>() {
      @Override
      public void onSuccess(List<Reaction> reactions) {
          Log.e(TAG, "Total Reactions: " + reactions.size());
          for (Reaction reaction : reactions) {
              Log.e(TAG, "Reaction: " + reaction.getReaction());
          }
      }

      @Override
      public void onError(CometChatException e) {
          Log.e(TAG, "Reaction fetch error: " + e.getMessage());
      }
    }); 
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val limit = 30
    val messageId = 1

    val reactionRequest = ReactionsRequest.ReactionsRequestBuilder()
          .setLimit(limit)
          .setMessageId(messageId)
          .build()

    reactionRequest.fetchPrevious(object : CometChat.CallbackListener<List<Reaction>>() {
      override fun onSuccess(reactions: List<Reaction>?) {
          Log.e(TAG, "Total Reactions: ${reactions?.size}")
          reactions?.forEach { reaction ->
              Log.e(TAG, "Reaction: ${reaction.reaction}")
          }
      }

      override fun onError(e: CometChatException?) {
          Log.e(TAG, "Reaction fetch error: ${e?.message}")
      }
    })
    ```
  </Tab>
</Tabs>

## Real-time Reaction Events

Keep the chat interactive with real-time updates for reactions. Register a listener for these events and make your UI responsive. For more information on listeners, see [Real-Time Listeners](/sdk/android/real-time-listeners).

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    private String listenerID = "UNIQUE_LISTENER_ID";

    CometChat.addMessageListener(listenerID, new CometChat.MessageListener() {
      @Override
      public void onMessageReactionAdded(ReactionEvent reactionEvent) {
          Log.e(TAG, "Reaction added");
      }

      @Override
      public void onMessageReactionRemoved(ReactionEvent reactionEvent) {
          Log.e(TAG, "Reaction removed");
      }
    });
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val listenerID = "UNIQUE_LISTENER_ID"

    CometChat.addMessageListener(listenerID, object : CometChat.MessageListener() {
      override fun onMessageReactionAdded(reactionEvent: ReactionEvent?) {
          Log.e(TAG, "Reaction added")
      }

      override fun onMessageReactionRemoved(reactionEvent: ReactionEvent?) {
          Log.e(TAG, "Reaction removed")
      }
    })
    ```
  </Tab>
</Tabs>

## Removing a Reaction Listener

To stop listening for reaction events, remove the listener as follows:

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    private String listenerID = "UNIQUE_LISTENER_ID";

    CometChat.removeMessageListener(listenerID);
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val listenerID = "UNIQUE_LISTENER_ID"

    CometChat.removeMessageListener(listenerID)   
    ```
  </Tab>
</Tabs>

<Warning>
  Always remove listeners when they're no longer needed (e.g., in `onDestroy()` or when navigating away). Failing to remove listeners can cause memory leaks and duplicate event handling.
</Warning>

## Get Reactions List

To retrieve the list of reactions reacted on particular message, you can use the `message.getReactions()` method. This method will return an array containing the reactions, or an empty array if no one reacted on the message.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    message.getReactions()
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    message.reactions 
    ```
  </Tab>
</Tabs>

## Check if Logged-in User has Reacted on Message

To check if the logged-in user has reacted on a particular message or not, You can use the `getReactedByMe()` method on any [`ReactionCount`](/sdk/reference/auxiliary#reactioncount) object instance. This method will return a boolean value, `true` if the logged-in user has reacted on that message, otherwise `false`.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    for (ReactionCount reactionCount : message.getReactions()) {
      Log.e(TAG, "isReactedByMe" + reactionCount.getReactedByMe()); //Return true is logged-in user reacted on that message, otherwise false
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    for (reactionCount in message.reactions) {
      Log.e(TAG, "isReactedByMe" + reactionCount.reactedByMe) //Return true is logged-in user reacted on that message, otherwise false
    }
    ```
  </Tab>
</Tabs>

## Update Message With Reaction Info

When a user adds or removes a reaction, you will receive a real-time event. Once you receive the real time event you would want to update the message with the latest reaction information. To do so you can use the `updateMessageWithReactionInfo()` method.

The `updateMessageWithReactionInfo()` method provides a seamless way to update the reactions on a message instance ([`BaseMessage`](/sdk/reference/messages#basemessage)) in real-time. This method ensures that when a reaction is added or removed from a message, the BaseMessage object's getReactions() property reflects this change immediately.

When you receive a real-time reaction event (`ReactionEvent`), call the `updateMessageWithReactionInfo()` method, passing the `BaseMessage` instance (message), the inner `Reaction` from the event (for example `reactionEvent.getReaction()`), and the reaction event action type (`CometChatConstants.REACTION_ADDED` or `CometChatConstants.REACTION_REMOVED`) that corresponds to the message being reacted to.

<Tabs>
  <Tab title="Java">
    ```java theme={null}
    // The message to which the reaction is related
    BaseMessage message = ...;

    // The reaction event data received in real-time
    Reaction messageReaction = ...;

    // The received reaction event real-time action type. Can be CometChatConstants.REACTION_ADDED or CometChatConstants.REACTION_REMOVED
    String action = CometChatConstants.REACTION_ADDED;

    BaseMessage modifiedBaseMessage = CometChatHelper.updateMessageWithReactionInfo(
    baseMessage, 
    messageReaction, 
    action
    );
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // The message to which the reaction is related
    val message: BaseMessage = ...

    // The reaction event data received in real-time
    val messageReaction: Reaction = ...

    // The received reaction event real-time action type. Can be CometChatConstants.REACTION_ADDED or CometChatConstants.REACTION_REMOVED
    val action = CometChatConstants.REACTION_ADDED

    // Update the BaseMessage instance with the new reaction information
    val modifiedBaseMessage: BaseMessage = CometChatHelper.updateMessageWithReactionInfo(
      message, 
      messageReaction, 
      action
    )
    ```
  </Tab>
</Tabs>

After calling this method, the `message` instance's reactions are updated. You can then use `message.getReactions()` to get the latest reactions and refresh your UI accordingly.

## Reaction Payload Structure

<Accordion title="Reaction Object">
  When fetching reactions for a message, each `Reaction` object contains the following fields:

  | Parameter   | Type                           | Description                            |
  | ----------- | ------------------------------ | -------------------------------------- |
  | `id`        | String                         | Unique reaction identifier             |
  | `messageId` | long                           | ID of the message that was reacted to  |
  | `reaction`  | String                         | The reaction emoji                     |
  | `uid`       | String                         | UID of the user who reacted            |
  | `reactedAt` | long                           | Unix timestamp when reaction was added |
  | `reactedBy` | [User](#user-object-reactions) | User who added the reaction            |

  **Sample Reaction Object:**

  ```json theme={null}
  {
    "id": "reaction_123",
    "messageId": 12345,
    "reaction": "👍",
    "uid": "user_123",
    "reactedAt": 1699900000,
    "reactedBy": {
      "uid": "user_123",
      "name": "John Doe",
      "avatar": "https://example.com/avatar.png",
      "status": "online",
      "role": "default",
      "tags": ["premium", "verified"]
    }
  }
  ```
</Accordion>

<Accordion title="User Object (Reactions)">
  The nested `User` object in `reactedBy` contains:

  | Parameter       | Type           | Description                                            |
  | --------------- | -------------- | ------------------------------------------------------ |
  | `uid`           | String         | Unique identifier of the user                          |
  | `name`          | String         | Display name of the user                               |
  | `avatar`        | String         | URL to user's profile picture                          |
  | `link`          | String         | URL to user's profile page                             |
  | `role`          | String         | User role for access control                           |
  | `metadata`      | JSONObject     | Custom data set by developer                           |
  | `status`        | String         | User online status. Values: `"online"`, `"offline"`    |
  | `statusMessage` | String         | Custom status message                                  |
  | `lastActiveAt`  | long           | Unix timestamp of last activity                        |
  | `hasBlockedMe`  | boolean        | Whether this user has blocked the logged-in user       |
  | `blockedByMe`   | boolean        | Whether the logged-in user has blocked this user       |
  | `tags`          | Array\<String> | List of tags for user identification                   |
  | `deactivatedAt` | long           | Unix timestamp when user was deactivated (0 if active) |
</Accordion>

<Accordion title="ReactionCount Object">
  When accessing reactions on a message via `message.getReactions()`, each `ReactionCount` object contains:

  | Parameter     | Type    | Description                                            |
  | ------------- | ------- | ------------------------------------------------------ |
  | `reaction`    | String  | The reaction emoji                                     |
  | `count`       | int     | Total count of this reaction                           |
  | `reactedByMe` | boolean | Whether the logged-in user has reacted with this emoji |

  **Sample ReactionCount Object:**

  ```json theme={null}
  {
    "reaction": "👍",
    "count": 5,
    "reactedByMe": true
  }
  ```
</Accordion>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Send Messages" icon="paper-plane" href="/sdk/android/send-message">
    Learn how to send text, media, and custom messages
  </Card>

  <Card title="Receive Messages" icon="envelope" href="/sdk/android/receive-messages">
    Handle real-time message events with listeners
  </Card>

  <Card title="Threaded Messages" icon="comments" href="/sdk/android/threaded-messages">
    Organize conversations with message threads
  </Card>

  <Card title="Mentions" icon="at" href="/sdk/android/mentions">
    Tag users in messages with @mentions
  </Card>
</CardGroup>
