---
title: "Social Features"
canonical_url: "https://apidocs.sportradar.com/resources/virtual-stadium/docs/sdk/centralHub/social"
markdown_url: "https://apidocs.sportradar.com/resources/virtual-stadium/docs/sdk/centralHub/social.md"
last_updated: "2026-04-16T10:19:11Z"
---

# Social Features

Follow users, load followers and following lists, and search within the Central Hub community.

## Following Users

`CentralHubFollowingManager` manages follow and unfollow actions and emits follow events so your UI can react immediately.

**Android**

```kotlin
class FollowingViewModel : ViewModel(), KoinComponent {

    private val followingManager: CentralHubFollowingManager = get()

    val followEvents = followingManager.followEvents

    suspend fun followUser(userId: String) {
        followingManager.followUser(
            userId = userId,
            onSuccess = { /* User followed */ },
            onFailure = { error -> /* Handle error */ },
        )
    }

    suspend fun unfollowUser(userId: String) {
        followingManager.unfollowUser(
            userId = userId,
            onSuccess = { /* User unfollowed */ },
            onFailure = { error -> /* Handle error */ },
        )
    }
}
```

**iOS**

```swift
class FollowingViewModel: ObservableObject {

    private let followingManager =
        KoinHelper().getCentralHubFollowingManager()

    func followUser(userId: String) async {
        await followingManager.followUser(
            userId: userId,
            onSuccess: { /* User followed */ },
            onFailure: { error in /* Handle error */ }
        )
    }

    func unfollowUser(userId: String) async {
        await followingManager.unfollowUser(
            userId: userId,
            onSuccess: { /* User unfollowed */ },
            onFailure: { error in /* Handle error */ }
        )
    }
}
```

## Viewing Followers

`CentralHubFollowersProvider` loads followers and following lists with sorting and pagination support.

### Sort Options

- `FollowersSortType.Latest` — newest followers first.
- `FollowersSortType.Earliest` — oldest followers first.

**Android**

```kotlin
class FollowersViewModel : ViewModel(), KoinComponent {

    private val followersProvider: CentralHubFollowersProvider = get()

    val followersState = followersProvider.state

    suspend fun loadFollowers(userId: String) {
        followersProvider.loadData(
            userId = userId,
            sortType = FollowersSortType.Latest,
            pageLimit = 20,
        )
    }

    fun loadMore(
        followingType: FollowingType,
        sortType: FollowersSortType,
    ) {
        followersProvider.loadNextPage(
            followingType = followingType,
            sortType = sortType,
            pageLimit = 20,
        )
    }
}
```

**iOS**

```swift
class FollowersViewModel: ObservableObject {

    private let followersProvider =
        KoinHelper().getCentralHubFollowersProvider()

    @Published var followersState: FollowersState?

    init() {
        subscribeToFollowers()
    }

    private func subscribeToFollowers() {
        followersProvider.state.subscribe { [weak self] state in
            self?.followersState = state
        }
    }

    func loadFollowers(userId: String) async {
        await followersProvider.loadData(
            userId: userId,
            sortType: FollowersSortType.latest,
            pageLimit: 20
        )
    }
}
```

## Searching for Users

`CentralHubSearchProvider` searches users across the community or within follower subsets.

### Search Types

- `SearchType.ALL` — search all users.
- `SearchType.FOLLOWING` — search only followed users.
- `SearchType.FOLLOWERS` — search only followers.

**Android**

```kotlin
class SearchViewModel : ViewModel(), KoinComponent {

    private val searchProvider: CentralHubSearchProvider = get()

    val searchState = searchProvider.state

    suspend fun search(
        query: String,
        searchType: SearchType = SearchType.ALL,
    ) {
        if (query.isNotBlank()) {
            searchProvider.search(
                query = query,
                searchType = searchType,
                pageLimit = 20,
            )
        }
    }

    suspend fun loadMoreResults(
        query: String,
        searchType: SearchType,
    ) {
        searchProvider.loadNextSearchPage(
            query = query,
            searchType = searchType,
            pageLimit = 20,
        )
    }

    fun clearSearch() {
        searchProvider.clear()
    }

    override fun onCleared() {
        super.onCleared()
        searchProvider.destroy()
    }
}
```

**iOS**

```swift
class SearchViewModel: ObservableObject {

    private let searchProvider =
        KoinHelper().getCentralHubSearchProvider()

    @Published var searchState: CentralHubSearchState?

    init() {
        subscribeToSearch()
    }

    private func subscribeToSearch() {
        searchProvider.state.subscribe { [weak self] state in
            self?.searchState = state
        }
    }

    func search(
        query: String,
        searchType: SearchType = .all
    ) async {
        guard !query.isEmpty else { return }

        await searchProvider.search(
            query: query,
            searchType: searchType,
            pageLimit: 20
        )
    }

    func loadMoreResults(
        query: String,
        searchType: SearchType
    ) async {
        await searchProvider.loadNextSearchPage(
            query: query,
            searchType: searchType,
            pageLimit: 20
        )
    }

    func clearSearch() {
        searchProvider.clear()
    }

    deinit {
        searchProvider.destroy()
    }
}
```

## Data Models

### FollowersState

```kotlin
data class FollowersState(
    val followers: List<Follower>,
    val following: List<Follower>,
    val followersCount: Int,
    val followingCount: Int,
    val followersNextPage: String?,
    val followingNextPage: String?,
    val loadingStatus: LoadingStatus,
    val nextPageLoadingStatus: LoadingStatus,
    val followActionLoadingStatus: LoadingStatus,
)
```

### CentralHubSearchState

```kotlin
data class CentralHubSearchState(
    val searchResults: List<Follower>,
    val loadingStatus: LoadingStatus,
    val nextPageLoadingStatus: LoadingStatus,
    val followActionLoadingStatus: LoadingStatus,
    val allDataLoaded: Boolean,
)
```

## Related Topics

- [User Profiles](https://apidocs.sportradar.com/resources/virtual-stadium/docs/sdk/centralHub/profiles.md) - View user profile details.
- [Notifications](https://apidocs.sportradar.com/resources/virtual-stadium/docs/sdk/centralHub/notifications.md) - Show new follower activity.
