> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-llms-scoped-indexes.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 |
  | - | - |
  | Package | `@cometchat/chat-sdk-react-native` |
  | Import | `import { CometChat } from "@cometchat/chat-sdk-react-native";` |
  | Key Classes | `CometChat.MessageListener`, `CometChat.MessagesRequestBuilder` |
  | Key Methods | `addMessageListener()`, `fetchPrevious()`, `fetchNext()`, `getUnreadMessageCount()`, `getLastDeliveredMessageId()`, `getMessageDetails()`, `getUnreadMessageCountForAllGroups()`, `getUnreadMessageCountForAllUsers()`, `getUnreadMessageCountForGroup()`, `getUnreadMessageCountForUser()`, `removeMessageListener()` |
  | Listener Events | `onTextMessageReceived`, `onMediaMessageReceived`, `onCustomMessageReceived` |
  | Prerequisites | SDK initialized, user logged in |
  | Primary output | `fetchNext()` / `fetchPrevious()` → `Promise<CometChat.BaseMessage[] \| []>`; listeners return `void` and deliver via callbacks |
  | Constraints | `fetchPrevious()` walks backwards through history; `fetchNext()` walks forward. Mixing them on one request object interleaves pages confusingly. Every `add*Listener()` needs a matching `remove*Listener()` with the same listener ID — unremoved listeners leak and fire after unmount. |
  | Related | [Send a Message](/sdk/react-native/send-message) · [Message Filtering](/sdk/react-native/additional-message-filtering) · [Delivery & Read Receipts](/sdk/react-native/delivery-read-receipts) |
  | Full reference | [`BaseMessage`](/sdk/reference/messages#basemessage) · [`TextMessage`](/sdk/reference/messages#textmessage) · [`MediaMessage`](/sdk/reference/messages#mediamessage) · [`CometChatException`](/sdk/reference/auxiliary#cometchatexception) |
</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>

## Card Messages

A [`CardMessage`](/sdk/react-native/campaigns#card-messages) (`category: "card"`) is delivered through the `onCardMessageReceived` callback of the `MessageListener`. Card messages are **receive-only** — they are created and sent via the Platform (REST) API or Dashboard Bubble Builder, not from the SDK.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    CometChat.addMessageListener(
      listenerID,
      new CometChat.MessageListener({
        onCardMessageReceived: (cardMessage: CometChat.CardMessage) => {
          console.log("Card message received", cardMessage);
          // getCard() returns the raw Card Schema JSON — pass it to your card renderer
          const card = cardMessage.getCard();
        },
      })
    );
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    CometChat.addMessageListener(
      listenerID,
      new CometChat.MessageListener({
        onCardMessageReceived: (cardMessage) => {
          console.log("Card message received", cardMessage);
          // getCard() returns the raw Card Schema JSON — pass it to your card renderer
          const card = cardMessage.getCard();
        },
      })
    );
    ```
  </Tab>
</Tabs>

For the full `CardMessage` field reference, see [Campaigns → Card Messages](/sdk/react-native/campaigns#card-messages).

## 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>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.