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

# Receive Messages

> Receive real-time messages, fetch unread messages, retrieve message history, search messages, and get unread counts using the CometChat React Native SDK.

<Accordion title="AI Integration Quick Reference">
  | Field           | Value                                                                               |
  | --------------- | ----------------------------------------------------------------------------------- |
  | Key Classes     | `CometChat.MessageListener`, `CometChat.MessagesRequestBuilder`                     |
  | Key Methods     | `addMessageListener()`, `fetchPrevious()`, `fetchNext()`, `getUnreadMessageCount()` |
  | Listener Events | `onTextMessageReceived`, `onMediaMessageReceived`, `onCustomMessageReceived`        |
  | Prerequisites   | SDK initialized, user logged in                                                     |
</Accordion>

Receiving messages with CometChat has two parts:

1. Adding a [real-time listener](#real-time-messages) to receive messages while your app is running
2. Fetching [unread](#unread-messages), or [historical](#message-history) messages when your app starts up or the user scrolls back

<Note>
  The TypeScript and JavaScript APIs are identical — the only difference is type annotations (e.g., `: string`, `: CometChat.BaseMessage[]`). The Real-Time Messages section shows both for reference. The remaining sections use TypeScript only to keep things concise — just drop the type annotations for plain JavaScript.
</Note>

## Real-Time Messages

Register a `MessageListener` to receive incoming messages as they arrive. Each callback receives the specific message subclass — [`TextMessage`](/sdk/reference/messages#textmessage), [`MediaMessage`](/sdk/reference/messages#mediamessage), or [`CustomMessage`](/sdk/reference/messages#custommessage).

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    let listenerID: string = "UNIQUE_LISTENER_ID";

    CometChat.addMessageListener(
      listenerID,
      new CometChat.MessageListener({
        onTextMessageReceived: (textMessage: CometChat.TextMessage) => {
          console.log("Text message received successfully", textMessage);
        },
        onMediaMessageReceived: (mediaMessage: CometChat.MediaMessage) => {
          console.log("Media message received successfully", mediaMessage);
        },
        onCustomMessageReceived: (customMessage: CometChat.CustomMessage) => {
          console.log("Custom message received successfully", customMessage);
        },
      })
    );
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    let listenerID = "UNIQUE_LISTENER_ID";

    CometChat.addMessageListener(
      listenerID,
      new CometChat.MessageListener({
        onTextMessageReceived: (textMessage) => {
          console.log("Text message received successfully", textMessage);
        },
        onMediaMessageReceived: (mediaMessage) => {
          console.log("Media message received successfully", mediaMessage);
        },
        onCustomMessageReceived: (customMessage) => {
          console.log("Custom message received successfully", customMessage);
        },
      })
    );
    ```
  </Tab>
</Tabs>

| Parameter    | Description                                                                       |
| ------------ | --------------------------------------------------------------------------------- |
| `listenerID` | An ID that uniquely identifies that listener. Use the same ID to remove it later. |

Remove the listener when you no longer need it:

```javascript theme={null}
CometChat.removeMessageListener("UNIQUE_LISTENER_ID");
```

<Warning>
  Always remove listeners when they're no longer needed (e.g., on component unmount). Failing to do so can cause memory leaks and duplicate event handling.
</Warning>

<Warning>
  As a sender, you will not receive your own message in a real-time event. However, if a user is logged in on multiple devices, they will receive the event on the other devices.
</Warning>

## Missed Messages

Fetch messages that were sent while the user was offline using `getLastDeliveredMessageId()` and `fetchNext()`.

<Tabs>
  <Tab title="One-on-One">
    ```typescript theme={null}
    let UID: string = "UID";
    let limit: number = 30;
    let latestId: number = await CometChat.getLastDeliveredMessageId();

    let messagesRequest: CometChat.MessagesRequest =
      new CometChat.MessagesRequestBuilder()
        .setUID(UID)
        .setMessageId(latestId)
        .setLimit(limit)
        .build();

    messagesRequest.fetchNext().then(
      (messages: CometChat.BaseMessage[]) => {
        console.log("Message list fetched:", messages);
      },
      (error: CometChat.CometChatException) => {
        console.log("Message fetching failed with error:", error);
      }
    );
    ```
  </Tab>

  <Tab title="Group">
    ```typescript theme={null}
    let GUID: string = "GUID";
    let limit: number = 30;
    let latestId: number = await CometChat.getLastDeliveredMessageId();

    let messagesRequest: CometChat.MessagesRequest =
      new CometChat.MessagesRequestBuilder()
        .setGUID(GUID)
        .setMessageId(latestId)
        .setLimit(limit)
        .build();

    messagesRequest.fetchNext().then(
      (messages: CometChat.BaseMessage[]) => {
        console.log("Message list fetched:", messages);
      },
      (error: CometChat.CometChatException) => {
        console.log("Message fetching failed with error:", error);
      }
    );
    ```
  </Tab>
</Tabs>

Call `fetchNext()` repeatedly on the same object to paginate through all missed messages.

## Unread Messages

Fetch unread messages by adding `setUnread(true)` to the builder. Use `fetchPrevious()` to retrieve them.

<Tabs>
  <Tab title="One-on-One">
    ```typescript theme={null}
    let UID: string = "UID";
    let limit: number = 30;

    let messagesRequest: CometChat.MessagesRequest =
      new CometChat.MessagesRequestBuilder()
        .setUID(UID)
        .setUnread(true)
        .setLimit(limit)
        .build();

    messagesRequest.fetchPrevious().then(
      (messages: CometChat.BaseMessage[]) => {
        console.log("Message list fetched:", messages);
      },
      (error: CometChat.CometChatException) => {
        console.log("Message fetching failed with error:", error);
      }
    );
    ```
  </Tab>

  <Tab title="Group">
    ```typescript theme={null}
    let GUID: string = "GUID";
    let limit: number = 30;

    let messagesRequest: CometChat.MessagesRequest =
      new CometChat.MessagesRequestBuilder()
        .setGUID(GUID)
        .setUnread(true)
        .setLimit(limit)
        .build();

    messagesRequest.fetchPrevious().then(
      (messages: CometChat.BaseMessage[]) => {
        console.log("Message list fetched:", messages);
      },
      (error: CometChat.CometChatException) => {
        console.log("Message fetching failed with error:", error);
      }
    );
    ```
  </Tab>
</Tabs>

<Note>
  Results are returned as [`BaseMessage`](/sdk/reference/messages#basemessage) objects, which may be instances of [`TextMessage`](/sdk/reference/messages#textmessage), [`MediaMessage`](/sdk/reference/messages#mediamessage), [`CustomMessage`](/sdk/reference/messages#custommessage), `Action`, or `Call`. Use the `instanceof` operator to check the type.
</Note>

## Message History

Fetch the full conversation history using `fetchPrevious()`. Call it repeatedly on the same request object to paginate — useful for implementing upward scrolling.

<Tabs>
  <Tab title="One-on-One">
    ```typescript theme={null}
    let UID: string = "UID";
    let limit: number = 30;

    let messagesRequest: CometChat.MessagesRequest =
      new CometChat.MessagesRequestBuilder()
        .setUID(UID)
        .setLimit(limit)
        .build();

    messagesRequest.fetchPrevious().then(
      (messages: CometChat.BaseMessage[]) => {
        console.log("Message list fetched:", messages);
      },
      (error: CometChat.CometChatException) => {
        console.log("Message fetching failed with error:", error);
      }
    );
    ```
  </Tab>

  <Tab title="Group">
    ```typescript theme={null}
    let GUID: string = "GUID";
    let limit: number = 30;

    let messagesRequest: CometChat.MessagesRequest =
      new CometChat.MessagesRequestBuilder()
        .setGUID(GUID)
        .setLimit(limit)
        .build();

    messagesRequest.fetchPrevious().then(
      (messages: CometChat.BaseMessage[]) => {
        console.log("Message list fetched:", messages);
      },
      (error: CometChat.CometChatException) => {
        console.log("Message fetching failed with error:", error);
      }
    );
    ```
  </Tab>
</Tabs>

The `fetchPrevious()` method returns an array of [`BaseMessage`](/sdk/reference/messages#basemessage) objects (which may be [`TextMessage`](/sdk/reference/messages#textmessage), [`MediaMessage`](/sdk/reference/messages#mediamessage), or other subclasses).

## Search Messages

Add `setSearchKeyword()` to the builder to filter messages by keyword.

<Tabs>
  <Tab title="One-on-One">
    ```typescript theme={null}
    let UID: string = "UID";
    let limit: number = 30;
    let searchKeyword: string = "Hello";

    let messagesRequest: CometChat.MessagesRequest =
      new CometChat.MessagesRequestBuilder()
        .setUID(UID)
        .setLimit(limit)
        .setSearchKeyword(searchKeyword)
        .build();

    messagesRequest.fetchPrevious().then(
      (messages: CometChat.BaseMessage[]) => {
        console.log("Message list fetched:", messages);
      },
      (error: CometChat.CometChatException) => {
        console.log("Message fetching failed with error:", error);
      }
    );
    ```
  </Tab>

  <Tab title="Group">
    ```typescript theme={null}
    let GUID: string = "GUID";
    let limit: number = 30;
    let searchKeyword: string = "Hello";

    let messagesRequest: CometChat.MessagesRequest =
      new CometChat.MessagesRequestBuilder()
        .setGUID(GUID)
        .setLimit(limit)
        .setSearchKeyword(searchKeyword)
        .build();

    messagesRequest.fetchPrevious().then(
      (messages: CometChat.BaseMessage[]) => {
        console.log("Message list fetched:", messages);
      },
      (error: CometChat.CometChatException) => {
        console.log("Message fetching failed with error:", error);
      }
    );
    ```
  </Tab>
</Tabs>

### Search Capabilities

By default, search only matches message text. With `Conversation & Advanced Search` enabled, it also matches file names, mentions, and MIME types.

| Feature          | Basic Search | Advanced Search |
| ---------------- | ------------ | --------------- |
| Text search      | ✅            | ✅               |
| File name search | ❌            | ✅               |
| Mentions search  | ❌            | ✅               |
| MIME type search | ❌            | ✅               |

<Note>
  `Conversation & Advanced Search` is available on `Advanced` and `Custom` [plans](https://www.cometchat.com/pricing). Enable it from the [CometChat Dashboard](https://app.cometchat.com) under Chats → Settings → General Configuration.
</Note>

## Unread Message Count

CometChat provides several methods to get unread counts at different scopes. All return a `Promise` that resolves with an object mapping IDs to counts.

Each method accepts an optional boolean parameter to exclude messages from blocked users.

| Method                                | Scope                     | Returns                               |
| ------------------------------------- | ------------------------- | ------------------------------------- |
| `getUnreadMessageCountForUser(UID)`   | Single user conversation  | `{ [UID]: count }`                    |
| `getUnreadMessageCountForGroup(GUID)` | Single group conversation | `{ [GUID]: count }`                   |
| `getUnreadMessageCountForAllUsers()`  | All user conversations    | `{ [UID]: count, ... }`               |
| `getUnreadMessageCountForAllGroups()` | All group conversations   | `{ [GUID]: count, ... }`              |
| `getUnreadMessageCount()`             | Everything                | `{ users: { ... }, groups: { ... } }` |

### Single Conversation

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    // One-on-one
    let UID: string = "UID";
    CometChat.getUnreadMessageCountForUser(UID).then(
      (count: Object) => console.log("Unread count:", count),
      (error: CometChat.CometChatException) => console.log("Error:", error)
    );

    // Group
    let GUID: string = "GUID";
    CometChat.getUnreadMessageCountForGroup(GUID).then(
      (count: Object) => console.log("Unread count:", count),
      (error: CometChat.CometChatException) => console.log("Error:", error)
    );
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    // One-on-one
    let UID = "UID";
    CometChat.getUnreadMessageCountForUser(UID).then(
      (count) => console.log("Unread count:", count),
      (error) => console.log("Error:", error)
    );

    // Group
    let GUID = "GUID";
    CometChat.getUnreadMessageCountForGroup(GUID).then(
      (count) => console.log("Unread count:", count),
      (error) => console.log("Error:", error)
    );
    ```
  </Tab>
</Tabs>

### All Conversations

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    // All users and groups combined
    CometChat.getUnreadMessageCount().then(
      (count: Object) => console.log("Unread count:", count),
      (error: CometChat.CometChatException) => console.log("Error:", error)
    );

    // All user conversations only
    CometChat.getUnreadMessageCountForAllUsers().then(
      (count: Object) => console.log("Unread count:", count),
      (error: CometChat.CometChatException) => console.log("Error:", error)
    );

    // All group conversations only
    CometChat.getUnreadMessageCountForAllGroups().then(
      (count: Object) => console.log("Unread count:", count),
      (error: CometChat.CometChatException) => console.log("Error:", error)
    );
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    // All users and groups combined
    CometChat.getUnreadMessageCount().then(
      (count) => console.log("Unread count:", count),
      (error) => console.log("Error:", error)
    );

    // All user conversations only
    CometChat.getUnreadMessageCountForAllUsers().then(
      (count) => console.log("Unread count:", count),
      (error) => console.log("Error:", error)
    );

    // All group conversations only
    CometChat.getUnreadMessageCountForAllGroups().then(
      (count) => console.log("Unread count:", count),
      (error) => console.log("Error:", error)
    );
    ```
  </Tab>
</Tabs>

### Excluding Blocked Users

Pass `true` as the last argument to any of the methods above:

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    CometChat.getUnreadMessageCountForUser(UID, true);
    CometChat.getUnreadMessageCountForGroup(GUID, true);
    CometChat.getUnreadMessageCount(true);
    CometChat.getUnreadMessageCountForAllUsers(true);
    CometChat.getUnreadMessageCountForAllGroups(true);
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    CometChat.getUnreadMessageCountForUser(UID, true);
    CometChat.getUnreadMessageCountForGroup(GUID, true);
    CometChat.getUnreadMessageCount(true);
    CometChat.getUnreadMessageCountForAllUsers(true);
    CometChat.getUnreadMessageCountForAllGroups(true);
    ```
  </Tab>
</Tabs>

## Get Message Details

Use `getMessageDetails()` to fetch a specific message by its ID. Returns the full message object ([`TextMessage`](/sdk/reference/messages#textmessage), [`MediaMessage`](/sdk/reference/messages#mediamessage), or [`CustomMessage`](/sdk/reference/messages#custommessage)).

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    let messageId: string = "MESSAGE_ID";

    CometChat.getMessageDetails(messageId).then(
      (message: CometChat.BaseMessage) => {
        console.log("Message details:", message);
      },
      (error: CometChat.CometChatException) => {
        console.log("Error fetching message details:", error);
      }
    );
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    let messageId = "MESSAGE_ID";

    CometChat.getMessageDetails(messageId).then(
      (message) => {
        console.log("Message details:", message);
      },
      (error) => {
        console.log("Error fetching message details:", error);
      }
    );
    ```
  </Tab>
</Tabs>

| Parameter   | Type     | Description                    |
| ----------- | -------- | ------------------------------ |
| `messageId` | `string` | The ID of the message to fetch |

Returns a [`BaseMessage`](/sdk/reference/messages#basemessage) object (which may be a [`TextMessage`](/sdk/reference/messages#textmessage), [`MediaMessage`](/sdk/reference/messages#mediamessage), or [`CustomMessage`](/sdk/reference/messages#custommessage)).

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Delivery & Read Receipts" icon="check-double" href="/sdk/react-native/delivery-read-receipts">
    Track when messages are delivered and read by recipients
  </Card>

  <Card title="Typing Indicators" icon="keyboard" href="/sdk/react-native/typing-indicators">
    Show real-time typing status in conversations
  </Card>
</CardGroup>
