> ## Documentation Index
> Fetch the complete documentation index at: /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.

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

> [!NOTE]
>
> Only conversation channels support channel presence. The SDK sync limit is 20 channel IDs at a time.

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

```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)
```

## Unsync All Channel Presence

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

```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()
```

## Best Practices

> [accordion] Bind syncing to visible rows
>
> 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] Use channel presence as a summary
>
> `isAnyMemberOnline` is designed for compact channel-list indicators. If you need per-user badges, sync those users directly with [User Presence](/social-plus-sdk/core-concepts/realtime-communication/presence-state/user-presence.md).

> [accordion] Start the current user's heartbeat
>
> Other members can only see the current user as online if the app enables presence and starts the current user's heartbeat.

## Related Topics

> [card] [User Presence](/social-plus-sdk/core-concepts/realtime-communication/presence-state/user-presence.md)
>
> Sync specific users when you need per-user online badges.

> [card] [Heartbeat Sync](/social-plus-sdk/core-concepts/realtime-communication/presence-state/heartbeat-sync.md)
>
> Mark the current user as online with the SDK heartbeat.


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