---
source_url: https://www.pubnub.com/docs/general/basics/receive-messages
title: Receive messages
updated_at: 2026-05-18T12:47:58.335Z
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Receive messages

Receiving messages (or any other events) is a three-step process:

1. Create a subscription or a subscription set.
2. Implement the appropriate event listener.
3. Subscribe to the subscription to start receiving real-time updates.

Before you begin, make sure you have initialized PubNub with your keys. PubNub delivers messages globally in under 30 ms and automatically recovers connections.

PubNub SDKs make this process easy with entities. Each entity provides operations for its own type. For example, `Channel` works on channels and `UserMetadata` works on user metadata. There are four [entities](https://www.pubnub.com/docs/general/entities) you can use:

* `Channel`
* `ChannelGroup`
* `UserMetadata`
* `ChannelMetadata`

:::warning Entity-enabled SDKs
Not all PubNub SDKs currently support entities. Refer to each SDK's [API documentation](https://www.pubnub.com/docs/sdks) for more information.
:::

You can subscribe to hundreds of channels with a single call. There are many [ways of subscribing](https://www.pubnub.com/docs/general/channels/subscribe), so choose the option that fits your use case.

###### JavaScript

```javascript
// create a subscription to a single channel
const channel = pubnub.channel('chats_inbox.user_1905')
const subscription1 = channel.subscription({ receivePresenceEvents: true });

// create a subscription to multiple channels
const channels = pubnub.subscriptionSet({ 
  channels: [
    "chats_guilds.mages_guild",
    "alerts.system",
    "geolocation.data"
  ] 
});
const subscription2 = channels.subscription();

// subscribe to both subscriptions and 
// start receiving real-time updates
subscription1.subscribe();
subscription2.subscribe();
```

###### Swift

```swift
// create a subscription to a single channel
let subscription1 = pubnub.channel("chats_inbox.user_1905").subscription()

// create a subscription to the channel, channel group, and
// user metadata updates
let subscriptionSet = pubnub.subscription(
  entities: [
    pubnub.channel("chats_guilds.mages_guild"),
    pubnub.channelGroup("alerts.system"),
    pubnub.userMetadata("user_1905_md")
  ],
  options: ReceivePresenceEvents()
)

// subscribe to both subscriptions and 
// start receiving real-time updates
subscription1.subscribe()
subscriptionSet.subscribe()
```

###### Objective-C

```objectivec
[self.pubnub subscribeToChannels: @[@"chats_guilds.mages_guild", @"alerts.system", @"geolocation.data"] withPresence:NO];
```

###### Java

```java
// Step 1: Create a subscription set
SubscriptionSet subscriptionSet = pubnub.subscriptionSetOf(
    Set.of("chats_guilds.mages_guild", "alerts.system", "geolocation.data"), 
    Collections.emptySet(), 
    EmptyOptions.INSTANCE);

// Step 2: Subscribe using the subscription set
subscriptionSet.subscribe();
```

###### C#

```csharp
SubscriptionSet subscriptionSet = pubnub.Subscription(
    new string[] {"chats_guilds.mages_guild", "alerts.system", "geolocation.data"}},
    SubscriptionOptions.ReceivePresenceEvents
)

subscriptionSet.Subscribe<object>()
```

###### Python

```python
channel1 = pubnub.channel("channelName")
channel2 = pubnub.channel("channelName2")
subscription_set1 = pubnub.subscription_set([channel, channel2])
subscription_set1.subscribe()
```

###### Dart

```dart
var subscription = pubnub.subscribe(channels: {'chats_guilds.mages_guild', 'alerts.system', 'geolocation.data'});
```

###### Kotlin

```kotlin
// create a subscription to a single channel
val myChannel = pubnub.channel("chats_inbox.user_1905")
val subscription = myChannel.subscription()

// create a subscription to multiple channels
val subscriptionSet = pubnub.subscriptionSetOf(
    // Specify channels with default options
    channels = setOf("chats_guilds.mages_guild","alerts.system","geolocation.data")
)

// subscribe to both subscriptions and 
// start receiving real-time updates
subscription.subscribe()
subscriptionSet.subscribe()
```

When you subscribe to a channel, your client receives all messages sent to it. To act on the data, implement an event listener.

The [event listener](https://www.pubnub.com/docs/general/messages/receive#add-an-event-handler) is the single entry point for messages, signals, and other events on your subscribed channels. Each data type has its own handler. Use handlers to define what your app does when it receives that type. For example, display the message content or trigger business logic.

:::note Subscription with Presence
To receive Presence events, you [subscribe with Presence](https://www.pubnub.com/docs/sdks/javascript/api-reference/publish-and-subscribe#subscribe) and have Presence enabled on your keyset. Make sure you configure Presence to track [Presence-related events](https://www.pubnub.com/docs/general/presence/overview#configuration) for all or selected channels (through [Presence Management rules](https://www.pubnub.com/docs/bizops-workspace/presence-management)).
:::

Add listeners to subscriptions and subscription sets to handle events from one or many subscriptions.

To handle another message type, such as a [signal](https://www.pubnub.com/docs/general/messages/publish#send-signals), add a `signal` handler to your listener. Each [handler has its own properties](https://www.pubnub.com/docs/general/messages/receive#add-an-event-handler) and maps to one message type.

The code below prints the message content and publisher using the `message` listener.

Every received message has an internal message type (immutable integer) and a custom message type (mutable string you define). These parameters let you filter, group, or [apply conditional logic to different types of messages](https://www.pubnub.com/docs/general/messages/type). The code below prints all messages.

:::note User ID / UUID
User ID is also referred to as **UUID/uuid** in some APIs and server responses but **holds the value** of the **userId** parameter you [set during initialization](https://www.pubnub.com/docs/general/setup/users-and-devices#set-the-user-id).
:::

###### JavaScript

```javascript
// add a subscription connection status listener
pubnub.addListener({
    status: (s) => {console.log('Status', s.category) }
});

// add message and presence listeners
subscription.addListener({
    // Messages
    message: (m) => { console.log('Received message', m) },
    // Presence
    presence: (p) => { console.log('Presence event', p) },
});
```

###### Swift

```swift
// add a subscription connection status listener
pubnub.onConnectionStateChange = { newStatus in
   print("Connection Status: \(newStatus)")   
}

// add message listener
subscription.onEvent = { event in
  switch event {
  case let .messageReceived(message):
    print("Message Received: \(message) Publisher: \(message.publisher ?? "defaultUUID")")
  default:
    break
  }
}
```

###### Objective-C

```objectivec
// Listener's class should conform to `PNEventsListener` protocol
// in order to have access to available callbacks.

// Adding listener.
[pubnub addListener:self];

// Callbacks listed below.

- (void)client:(PubNub *)pubnub didReceiveMessage:(PNMessageResult *)message {
    id msg = message.data.message; // Message payload
    NSString *publisher = message.data.publisher; // Message publisher
}
```

###### Java

```java
pubnub.addListener(new EventListener() {
    // Messages
    @Override
    public void message(PubNub pubnub, PNMessageResult message) {
        String messagePublisher = message.getPublisher();
        System.out.println("Message publisher: " + messagePublisher);
        System.out.println("Message Payload: " + message.getMessage());
    }
});
```

###### C#

```csharp
Subscription subscription1 = pubnub.Channel("channelName").Subscription()

subscription1.OnMessage = (Pubnub pn, PNMessageResult<object> messageEvent) => {
 Console.WriteLine($"Message received {messageEvent.Message}");
};

subscription1.Subscribe<object>()
```

###### Python

```python
subscription = pubnub.channel(f'{channel1}').subscription()

def on_message(listener):
    def message_callback(message):
        print(f"\033[94mMessage received on: {listener}: \n{message.message}\033[0m\n")
    return message_callback

def on_message_action(message_action):
    print(f"\033[5mMessageAction received: \n{message_action.value}\033[0m\n")

subscription.on_message = on_message('message_listener')
subscription.on_message_action = on_message_action

subscription.subscribe()
```

###### Dart

```dart
subscription.messages.listen((envelope) {
  switch (envelope.messageType) {
    case MessageType.normal:
      print('User with id ${envelope.uuid} sent a message: ${envelope.content}');
      break;
    default:
      print('User with id ${envelope.uuid} sent a message: ${envelope.content}');
  }
});
```

###### Kotlin

```kotlin
// add the subscribe connection status listener
pubnub.addListener(object : StatusListener() {
    override fun status(pubnub: PubNub, status: PNStatus) {
        // This block is executed asynchronously for each status update
        println("Connection Status: ${status.category}")
    }
})

// add the message and signal listeners
subscription.addListener(object : EventListener {
    override fun message(pubnub: PubNub, message: PNMessageResult) {
        // Log or process message
        println("Message: ${message.message}")
    }
    
    override fun signal(pubnub: PubNub, signal: PNSignalResult) {
        // Handle signals
        println("Signal: ${signal.message}")
    }
})
```

You can enhance published messages by [attaching emojis, actions, or delivery acknowledgements](https://www.pubnub.com/docs/general/messages/actions).

You can also [persist and retrieve older messages](https://www.pubnub.com/docs/general/basics/retrieve-old-messages), not only the ones sent in real time.

## Terms in this document

* **Channel** - A pathway for sending and receiving messages between devices, created automatically when you first use it, that can handle any number of users and messages for different communication needs, like 1-1 text chats, group conversations, and other data streaming.
* **Listener** - A function or objectthat reacts to events or messages, like new chat messages or connection updates, letting your app respond in real-time.
