---
source_url: https://www.pubnub.com/docs/general/basics/check-user-presence
title: Check user presence
updated_at: 2026-05-18T11:22:28.683Z
---

> 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


# Check user presence

PubNub lets you track the online and offline status of users and devices in real time. You can see who is online, when a user joins or leaves a channel, and which channels a user is subscribed to. Learn the basics in [Presence fundamentals](https://www.pubnub.com/docs/general/presence/overview).

:::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)).
:::

Before you begin, make sure you have initialized PubNub with your keys. The code below prints a [list of all users who are online](https://www.pubnub.com/docs/general/presence/overview) on the `chats.public.release_announcements` channel.

:::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
pubnub.hereNow(
  {
    channels: ["chats.public.release_announcements"]
  },
  function (status, response) {
    console.log(status, response);
  }
);
```

###### Swift

```swift
pubnub.hereNow(on: ["chats.public.release_announcements"]),
  includeUUIDs: true, also: true { result in
    switch result {
      case let .success(response):
        print("Successful hereNow Response: \(response)")

      case let .failure(error):
        print("Failed hereNow Response: \(error.localizedDescription)")
    }
})
```

###### Objective-C

```objectivec
[self.pubnub hereNowForChannel: @[@"chats.public.release_announcements"]
    withVerbosity:PNHereNowState
    completion:^(PNPresenceChannelHereNowResult *result, PNErrorStatus *status) {
  // parse the HereNow result parameter
}];
```

###### Java

```java
pubnub.hereNow()
  .channels(Arrays.asList("chats.public.release_announcements"))
  .includeState(true)
  .async(result -> {
      result.onSuccess(res -> {
          for (PNHereNowChannelData channelData : res.getChannels().values()) {
              System.out.println("---");
              System.out.println("channel:" + channelData.getChannelName());
              System.out.println("occupancy: " + channelData.getOccupancy());
              System.out.println("occupants:");

              for (PNHereNowOccupantData occupant : channelData.getOccupants()) {
                  System.out.println("uuid: " + occupant.getUuid()
                          + " state: " + occupant.getState());
              }
          }
      }).onFailure(exception -> {
          exception.printStackTrace();
      });
  });
```

###### C#

```csharp
pubnub.HereNow()
  .Channels(new string[] {"chats.public.release_announcements"})
  .IncludeState(true)
  .Execute(new PNHereNowResultEx((result, status) => {
    if (status.Error) {
      Console.WriteLine("HereNow error: " + status);
    }
    else if (result.Channels != null && result.Channels.Count > 0) {
      foreach (KeyValuePair<string, PNHereNowChannelData> kvp in result.Channels) {
        PNHereNowChannelData channelData = kvp.Value;
        Console.WriteLine("---");
        Console.WriteLine("channel:" + channelData.ChannelName);
        Console.WriteLine("occupancy:" + channelData.Occupancy);
        Console.WriteLine("Occupants:");

        if (channelData.Occupants != null && channelData.Occupants.Count > 0) {
          for (int index = 0; index < channelData.Occupants.Count; index++) {
            PNHereNowOccupantData occupant = channelData.Occupants[index];
            Console.WriteLine(string.Format("uuid: {0}", occupant.Uuid));
            Console.WriteLine(string.Format("state:{1}", (occupant.State != null) ?
            pubnub.JsonPluggableLibrary.SerializeToJsonString(occupant.State) : ""));
          }
        }
      }
    }
  }
));
```

###### Python

```python
def here_now_callback(result, status):
  if status.is_error():
    print("here_now error: %s" % status)
    return

  for channel_data in result.channels:
    print("---")
    print("channel: %s" % channel_data.channel_name)
    print("occupancy: %s" % channel_data.occupancy)

    print("occupants: %s" % channel_data.channel_name)

    for occupant in channel_data.occupants:
      print("uuid: %s, state: %s" % (occupant.uuid, occupant.state))

pubnub.here_now()\
  .channels("chats.public.release_announcements")\
  .include_state(True)\
  .pn_async(here_now_callback)
```

###### Dart

```dart
var result = await pubnub.hereNow(channels: {'chats.public.release_announcements'});
```

###### Kotlin

```kotlin
pubnub.hereNow(
    channels = listOf("chats.public.release_announcements"),
    includeUUIDs = true,
    includeState = true
).async { result, status ->
    if (status.error) {
        // handle error
        status.exception?.printStackTrace()
        return@async
    }
    result!!.channels.values.forEach { channelData ->
        println("---")
        println("Channel: ${channelData.channelName}")
        println("Occupancy: ${channelData.occupancy}")
        println("Occupants:")
        channelData.occupants.forEach { o ->
            println("UUID: ${o.uuid}, state: ${o.state}")
        }
    }
}
```

Presence relies on [presence events](https://www.pubnub.com/docs/general/presence/presence-events) that PubNub sends automatically when a user’s state changes. You can [react to these events](https://www.pubnub.com/docs/general/presence/presence-events#add-presence-listeners) by adding a handler dedicated to presence events.

:::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)).
:::

PubNub sends presence events on a presence channel, not on the channel where the change happens. A presence channel is created automatically for every regular channel.

If you need real‑time presence changes, enable presence when you subscribe to the regular channel.

###### JavaScript

```javascript
// subscribe to a single channel without presence
pubnub.subscribe({channels: ["chats_inbox.user_1905"]});

// subscribe to multiple channels with presence
pubnub.subscribe({
    channels: [
        "chats_guilds.mages_guild",
        "alerts.system",
        "geolocation.data"
    ],
    withPresence: true
});
```

###### Swift

```swift
pubnub.subscribe(
  to: ["chats.public.release_announcements"],
  withPresence: true
)
```

###### Objective-C

```objectivec
[self.pubnub subscribeToChannels: @[@"chats_guilds.mages_guild", @"chats_inbox.user_1905"] withPresence:YES];
```

###### Java

```java
pubnub.subscribe()
  .channels(Arrays.asList("chats.public.release_announcements"))
  .withPresence().execute();
```

###### C#

```csharp
Subscription subscription1 = pubnub.Channel("chats.public.release_announcements").Subscription(SubscriptionOptions.ReceivePresenceEvents)

subscription1.Subscribe<object>()
```

###### Python

```python
subscription = pubnub.channel_group('chats.public.release_announcements').subscription(with_presence = True)
subscription.subscribe()
```

###### Dart

```dart
var channel = "chats.public.release_announcements";
var subscription = pubnub.subscribe(channels: {channel}, withPresence: true);
```

###### Kotlin

```kotlin
pubnub.subscribe(
    channels = listOf("chats.public.release_announcements")
    withPresence = true
)
```

As part of user presence, you can [set a custom dynamic state](https://www.pubnub.com/docs/general/presence/presence-state), such as a score or mood indicator, for users in your channels. This state persists only while the user is subscribed to a channel. When the user disconnects, the custom data is removed.

If you don't want to lose any additional data about your users and channels, consider [adding metadata](https://www.pubnub.com/docs/general/basics/add-custom-metadata).

## 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.
* **Channel pattern** - A way to group and analyze channel data to track performance metrics like message counts and user engagement over time with PubNub Insights.
