# Troubleshooting

Common issues and solutions when integrating the Stream Chat Android SDK.

## Initialization Issues

### ChatClient Not Initialized

**Symptom:** `IllegalStateException: ChatClient is not initialized`

**Cause:** Attempting to use `ChatClient.instance()` before calling `ChatClient.Builder(...).build()`.

**Solution:** Initialize ChatClient in your `Application` class:

```kotlin
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        val client = ChatClient.Builder(apiKey, this)
            .withPlugins(
                StreamOfflinePluginFactory(appContext = this),
                StreamStatePluginFactory(config = StatePluginConfig(), appContext = this),
            )
            .build()
    }
}
```

### ProGuard/R8 Issues

**Symptom:** Crashes in release builds, missing classes, or serialization errors.

**Cause:** ProGuard/R8 obfuscation removing required classes.

**Solution:** The SDK includes consumer ProGuard rules automatically. See the [consumer rules in the SDK repository](https://github.com/GetStream/stream-chat-android/blob/develop/stream-chat-android-client/consumer-proguard-rules.pro) for details. If you still encounter issues, ensure the consumer rules are being applied correctly by your build configuration.

## Push Notification Issues

### FCM Token Not Refreshing

**Symptom:** Push stops working after token refresh.

**Solution:** Use `FirebaseMessagingDelegate` to handle token registration and refresh:

```kotlin
class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onNewToken(token: String) {
        FirebaseMessagingDelegate.registerFirebaseToken(
            token = token,
            providerName = "MyFirebaseProvider", // Must match dashboard config
        )
    }

    override fun onMessageReceived(message: RemoteMessage) {
        FirebaseMessagingDelegate.handleRemoteMessage(message)
    }
}
```

Alternatively, you can manually register the device using `addDevice`:

```kotlin
ChatClient.instance().addDevice(
    Device(
        token = token,
        pushProvider = PushProvider.FIREBASE,
        providerName = "MyFirebaseProvider",
    )
).enqueue { /* Handle result */ }
```

## State & UI Issues

### Messages Not Updating

**Symptom:** New messages don't appear or UI doesn't reflect changes.

**Cause:** The channel is not being watched. Messages only update in real-time for watched channels.

**Solution:** Ensure the channel is watched before expecting real-time updates:

```kotlin
// Watch the channel to receive real-time updates
ChatClient.instance().channel(channelType, channelId).watch().enqueue { result ->
    when (result) {
        is Result.Success -> { /* Channel is now watched */ }
        is Result.Failure -> { /* Handle error */ }
    }
}
```

For Compose, use the provided ViewModels which handle watching automatically:

```kotlin
val viewModelFactory = MessagesViewModelFactory(
    context = context,
    channelId = cid,
)
val messageListViewModel = viewModel<MessageListViewModel>(factory = viewModelFactory)
```

### Channel List Not Refreshing

**Symptom:** Channel list shows stale data or doesn't update with new messages.

**Cause:** Event handling not configured or custom filter issues.

**Solution:**

1. Verify you're using the SDK's ViewModel or observing state correctly
2. Check your `ChatEventHandler` if using custom event handling (see [Channels State and Filtering](/chat/docs/sdk/android/v6/client/guides/channels/))
3. Ensure the `StatePlugin` is configured

### Compose Recomposition Issues

**Symptom:** Compose UI updates excessively or not at all.

**Solution:** Use the SDK's state hoisting pattern:

```kotlin
// Let the ViewModel handle state
val messagesState by messageListViewModel.currentMessagesState.collectAsStateWithLifecycle()

MessageList(
    currentState = messagesState,
    // ...
)
```

Avoid creating new objects in composition that would trigger recomposition.

## Connection Issues

### Frequent Disconnections

**Symptom:** WebSocket disconnects frequently, especially on mobile networks.

**Cause:** Network changes or aggressive keep-alive settings.

**Solution:** Handle connectivity changes:

```kotlin
ChatClient.instance().clientState.connectionState
    .onEach { state ->
        when (state) {
            is ConnectionState.Connected -> { /* Online */ }
            is ConnectionState.Connecting -> { /* Reconnecting */ }
            is ConnectionState.Offline -> { /* Handle offline */ }
        }
    }
    .launchIn(scope)
```

### Token Expiry

**Symptom:** `401 Unauthorized` errors or connection failures after some time.

**Cause:** JWT token expired and `tokenProvider` not configured.

**Solution:** Provide a token provider that fetches fresh tokens:

```kotlin
ChatClient.Builder(apiKey, context)
    .withPlugins(/* ... */)
    .build()

// Connect with token provider
ChatClient.instance().connectUser(
    user = user,
    tokenProvider = {
        // Fetch fresh token from your backend
        myBackend.getStreamToken(userId)
    }
).enqueue { result ->
    // Handle result
}
```

For more details on handling token expiry with push notifications, see the [Push Notifications documentation](/chat/docs/sdk/android/v6/client/guides/push-notifications/#handling-expired-jwt-tokens).

## Memory & Performance

### Message List Performance

**Symptom:** Laggy scrolling in channels with many messages.

**Solution:**

1. Use `MessageLimitConfig` to limit in-memory messages
2. For Compose, the `MessageList` uses `LazyColumn` which virtualizes automatically
3. For XML Views, ensure you're not blocking the main thread in custom view holders

## Debugging Tips

### Enable Logging

Enable detailed logging to diagnose issues:

```kotlin
ChatClient.Builder(apiKey, context)
    .logLevel(ChatLogLevel.ALL)
    .loggerHandler(AndroidStreamLogger())
    .build()
```

Filter logcat by tag `Chat:` to see SDK logs.

### Inspect Network Requests

Use the `ApiRequestsAnalyser` to track API calls:

```kotlin
val analyser = ApiRequestsAnalyser.get()
analyser.dumpRequestByName("QueryChannels")
```

### Check Connection State

Monitor connection state for debugging:

```kotlin
ChatClient.instance().clientState.connectionState.value
ChatClient.instance().clientState.user.value
ChatClient.instance().clientState.initializationState.value
```


---

This page was last updated at 2026-04-17T17:33:32.154Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/android/v6/resources/troubleshooting/](https://getstream.io/chat/docs/sdk/android/v6/resources/troubleshooting/).