> ## Documentation Index
> Fetch the complete documentation index at: https://learn.social.plus/llms.txt
> Use this file to discover all available pages before exploring further.

# Channel Presence

> Sync conversation channel member presence with AmityChannelPresenceRepository on iOS and Android.

Channel presence tells your app whether any other member of a conversation channel is online. Use it for chat lists, member lists, and compact "active now" indicators.

<Warning>
  Channel presence is available on iOS and Android only. The current TypeScript and Flutter SDKs in this checkout do not expose channel presence APIs.
</Warning>

## Platform Surface

| Platform   | Repository                                       | Main APIs                                                                                                                                         |
| ---------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| iOS        | `AmityChannelPresenceRepository()`               | `syncChannelPresence(id:viewId:)`, `unsyncChannelPresence(id:viewId:)`, `unsyncAllChannelPresence()`, `getSyncingChannelPresence()`               |
| Android    | `AmityChatClient.newChannelPresenceRepository()` | `syncChannelPresence(channelId, viewId)`, `unsyncChannelPresence(channelId, viewId)`, `unsyncAllChannelPresence()`, `getSyncingChannelPresence()` |
| TypeScript | Not available                                    | Not available                                                                                                                                     |
| Flutter    | Not available                                    | Not available                                                                                                                                     |

<Info>
  Only conversation channels support channel presence. The SDK sync limit is 20 channel IDs at a time.
</Info>

## Parameters

| Operation                   | Parameter          | Required | Description                                                                                                                               |
| --------------------------- | ------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `syncChannelPresence`       | `id` / `channelId` | Yes      | Conversation channel ID whose members' presence should be refreshed periodically.                                                         |
| `syncChannelPresence`       | `viewId`           | No       | Stable view identifier. Defaults to `amity-global`; use a custom value when the same channel can appear in multiple visible UI locations. |
| `unsyncChannelPresence`     | `id` / `channelId` | Yes      | Channel ID to remove from syncing.                                                                                                        |
| `unsyncChannelPresence`     | `viewId`           | No       | Must match the `viewId` used when syncing if you passed a custom value.                                                                   |
| `unsyncAllChannelPresence`  | None               | No       | Stops syncing all channel presence tracked by the SDK presence engine.                                                                    |
| `getSyncingChannelPresence` | None               | No       | Returns iOS `AnyPublisher<[AmityChannelPresence], Error>` or Android `Flowable<List<AmityChannelPresence>>`.                              |

## Channel Presence Object

| Field                   | iOS                          | Android                        | Description                                                            |
| ----------------------- | ---------------------------- | ------------------------------ | ---------------------------------------------------------------------- |
| Channel ID              | `presence.channelId`         | `presence.getChannelId()`      | The conversation channel represented by the presence record.           |
| User presences          | `presence.userPresences`     | `presence.getUserPresences()`  | Presence records for members in the channel.                           |
| Any other member online | `presence.isAnyMemberOnline` | `presence.isAnyMemberOnline()` | `true` when at least one member other than the current user is online. |

## Sync Channel Presence

Start syncing when a conversation channel becomes visible, then unsync it when the row or screen is gone.

<CodeGroup>
  ```swift iOS theme={null}
  let repository = AmityChannelPresenceRepository()

  let cancellable = repository.getSyncingChannelPresence()
      .sink(receiveCompletion: { completion in
          if case let .failure(error) = completion {
              handleError(error)
          }
      }, receiveValue: { presences in
          for presence in presences {
              let isAnyMemberOnline = presence.isAnyMemberOnline
              showSuccessMessage("\(presence.channelId): \(isAnyMemberOnline)")
          }
      })

  repository.syncChannelPresence(id: channelId)

  // Call when the row or screen is no longer visible.
  repository.unsyncChannelPresence(id: channelId)

  _ = cancellable
  ```

  ```kotlin Android theme={null}
  val repository = AmityChatClient.newChannelPresenceRepository()

  repository.getSyncingChannelPresence()
      .observeOn(AndroidSchedulers.mainThread())
      .subscribe({ presences ->
          presences.forEach { presence ->
              val isAnyMemberOnline = presence.isAnyMemberOnline()
              showSuccessMessage("${presence.getChannelId()}: $isAnyMemberOnline")
          }
      }, { error ->
          showErrorMessage(error = error)
      })

  repository.syncChannelPresence(channelId)

  // Call when the row or screen is no longer visible.
  repository.unsyncChannelPresence(channelId)
  ```
</CodeGroup>

## Unsync All Channel Presence

Use `unsyncAllChannelPresence` when leaving a channel list, tearing down a view model, or replacing the whole visible channel set.

<CodeGroup>
  ```swift iOS theme={null}
  let repository = AmityChannelPresenceRepository()

  repository.syncChannelPresence(id: channelId)

  // Later, when the channel list is dismissed.
  repository.unsyncAllChannelPresence()
  ```

  ```kotlin Android theme={null}
  val repository = AmityChatClient.newChannelPresenceRepository()

  repository.syncChannelPresence(channelId)

  // Later, when the channel list is dismissed.
  repository.unsyncAllChannelPresence()
  ```
</CodeGroup>

## Best Practices

<AccordionGroup>
  <Accordion title="Bind syncing to visible rows" icon="eye">
    Sync a channel when its conversation row appears. Unsync during row reuse, unmount, or screen dismissal so the app stays under the 20-channel sync limit.
  </Accordion>

  <Accordion title="Use channel presence as a summary" icon="messages-square">
    `isAnyMemberOnline` is designed for compact channel-list indicators. If you need per-user badges, sync those users directly with <a href="/social-plus-sdk/core-concepts/realtime-communication/presence-state/user-presence">User Presence</a>.
  </Accordion>

  <Accordion title="Start the current user's heartbeat" icon="heart-pulse">
    Other members can only see the current user as online if the app enables presence and starts the current user's heartbeat.
  </Accordion>
</AccordionGroup>

## Related Topics

<CardGroup cols={2}>
  <Card title="User Presence" icon="user" href="/social-plus-sdk/core-concepts/realtime-communication/presence-state/user-presence">
    Sync specific users when you need per-user online badges.
  </Card>

  <Card title="Heartbeat Sync" icon="heart-pulse" href="/social-plus-sdk/core-concepts/realtime-communication/presence-state/heartbeat-sync">
    Mark the current user as online with the SDK heartbeat.
  </Card>
</CardGroup>
