cometchat-flutter-v6-troubleshooting
SkillDev toolsDiagnose a broken CometChat Flutter integration — blank screens, unbounded-height crashes, lists that don't fill, login and Region failures, calls that never ring, push that never arrives, and v5 leftovers. Symptom → cause → fix. Triggers: 'cometchat not working flutter', 'blank chat screen', 'Rende
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the cometchat-flutter-v6-troubleshooting skill
What this skill tells your AI
The instructions your AI receives, as published by cometchat/cometchat-skills in skills/cometchat-flutter-v6-troubleshooting/SKILL.md and read by ahel’s review.
Ground truth:
cometchat_chat_uikit: ^6.0— pub-cache source +ui-kit/flutter. Official docs: https://www.cometchat.com/docs/ui-kit/flutter/overview · Docs MCP:claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp(or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.
CometChat Flutter UIKit v6 — Troubleshooting Guide
Comprehensive guide for diagnosing and fixing CometChat Flutter UIKit v6 integration problems.
1. Quick Diagnosis Flow
Use this decision tree to jump to the right section:
What's happening?
│
├─ App crashes or errors on startup
│ └─ Go to → Section 2: Init & Login Errors
│
├─ UI looks wrong, layout broken, keyboard issues
│ └─ Go to → Section 3: UI Rendering Issues
│
├─ Calls not working, call screen blank or stuck
│ ├─ Outgoing screen NEVER renders (peer rings, caller shows nothing) → Section 4.7 (V6 navigatorKey trap)
│ ├─ Stuck on "Calling…" after peer accepts → Section 4.8 (upgrade to 6.0.1)
│ └─ Otherwise → Section 4: Call Issues
│
├─ Events not firing, duplicate events, memory leaks
│ └─ Go to → Section 5: Listener Issues
│
├─ Build fails on Android or iOS
│ └─ Go to → Section 6: Build Errors
│
├─ App is slow, janky scrolling, laggy keyboard
│ └─ Go to → Section 7: Performance Issues
│
└─ Platform-specific weirdness (Android/iOS/Web)
└─ Go to → Section 8: Platform-Specific Issues
2. Init & Login Errors
2.1 "Authentication null"
- Symptom: Error message
Authentication nullorPlease log in to CometChat before calling this methodwhen using any CometChat component or SDK call. - Cause:
CometChatUIKit.init()was not called, or was called but not awaited before using components or calling login. - Fix: Ensure
init()completes before any other CometChat usage:
// ✅ CORRECT — await init before anything else
final settings = (UIKitSettingsBuilder()
..appId = 'APP_ID'
..region = 'us'
..authKey = 'AUTH_KEY'
..subscriptionType = CometChatSubscriptionType.allUsers)
.build();
await CometChatUIKit.init(
uiKitSettings: settings,
onSuccess: (_) => debugPrint('Init done'),
onError: (e) => debugPrint('Init failed: ${e.message}'),
);
// ❌ WRONG — login before init completes (race condition)
CometChatUIKit.init(uiKitSettings: settings);
CometChatUIKit.login('uid');
2.2 "APP ID null"
- Symptom: Error
APP ID nullorappId is requiredduring init. - Cause:
appIdnot set inUIKitSettingsBuilder. - Fix: Set
appIdbefore calling.build():
final settings = (UIKitSettingsBuilder()
..appId = 'YOUR_APP_ID' // ← Must be set
..region = 'us'
..authKey = 'YOUR_AUTH_KEY')
.build();
2.3 ERR_ALREADY_LOGGED_IN
- Symptom: Error
ERR_ALREADY_LOGGED_INwhen callingCometChatUIKit.login(). - Cause: Calling login when a session already exists. After
init(), the SDK restores cached sessions automatically. - Fix: Check
CometChatUIKit.loggedInUserafter init before calling login:
CometChatUIKit.init(
uiKitSettings: settings,
onSuccess: (_) {
if (CometChatUIKit.loggedInUser != null) {
// Already logged in — skip login, go to home
navigateToHome();
} else {
// No session — show login screen
navigateToLogin();
}
},
);
2.4 "Android internal error" on login
- Symptom: Login fails with a vague
Android internal errormessage. - Cause: Multiple possible causes — incorrect auth key, UID doesn't exist in CometChat dashboard, beta SDK bug, or network issue.
- Fix:
- Verify credentials are correct in the CometChat dashboard
- Verify the UID exists in the dashboard
- Try calling
CometChat.login(uid, authKey)directly to isolate UIKit vs SDK issue - If using beta SDK, try the stable release
- Check network connectivity and firewall rules
2.5 Guard screen stuck on spinner
- Symptom: App shows a loading spinner forever after init. The auth guard never resolves.
- Cause: Using the callback-based
CometChat.getLoggedInUser()after init instead of the synchronousCometChatUIKit.loggedInUser. The callback API silently fails when no session exists — neitheronSuccessnoronErrorfires. - Fix: Use the synchronous check after init:
// ✅ CORRECT — synchronous check, always resolves
CometChatUIKit.init(
uiKitSettings: settings,
onSuccess: (_) {
final hasUser = CometChatUIKit.loggedInUser != null;
setState(() {
_loggedIn = hasUser;
_initializing = false;
});
},
);
// ❌ WRONG — callback may never fire when no session exists
CometChatUIKit.init(
uiKitSettings: settings,
onSuccess: (_) {
CometChat.getLoggedInUser(
onSuccess: (user) { /* may never fire */ },
onError: (e) { /* may never fire */ },
);
},
);
// ❌ ALSO WRONG — redundant native bridge round-trip
CometChatUIKit.init(
uiKitSettings: settings,
onSuccess: (_) async {
final user = await CometChatUIKit.getLoggedInUser(); // Unnecessary!
},
);
2.6 Region error (ERR_INVALID_REGION)
- Symptom: Init fails with
ERR_INVALID_REGION. - Cause: Region string is uppercase or not one of the valid values.
- Fix: Use lowercase region string — valid values are
'us','eu','in':
// ✅ CORRECT
..region = 'us'
// ❌ WRONG
..region = 'US'
..region = 'United States'
2.7 StateError from uninitialized ServiceLocator
- Symptom:
StateError: not initializedwhen creating a BLoC manually. - Cause: Component's
ServiceLocator.instance.setup()was not called before creating the BLoC. UIKit widgets do this automatically, but manual BLoC creation requires it. - Fix: Call setup before creating the BLoC:
// ✅ CORRECT
ConversationsServiceLocator.instance.setup();
final bloc = ConversationsBloc(
getLoggedInUserUseCase: ConversationsServiceLocator.instance.getLoggedInUserUseCase,
);
// ❌ WRONG — setup not called
final bloc = ConversationsBloc(
getLoggedInUserUseCase: ConversationsServiceLocator.instance.getLoggedInUserUseCase,
);
3. UI Rendering Issues
3.1 Double keyboard compensation (layout jumps) — PRE-6.0.1 symptom
- Symptom: When the keyboard opens, the message list jumps or there's extra white space. Content shifts twice — once from Flutter's Scaffold resize, once from the composer's internal keyboard handling.
- Cause: A pre-6.0.1 kit. Before kit fix ENG-34434, the composer did not clamp its keyboard spacing to Flutter's
viewInsets, so a Scaffold withresizeToAvoidBottomInset: true(the default) double-compensated. On^6.0.1the composer clamps toviewInsets, sotrueis correct and does NOT double-compensate. - Fix: Upgrade
cometchat_chat_uikitto^6.0.1and keepresizeToAvoidBottomInset: true(or omit it —trueis the default). Settingfalseis only a stopgap on old kits you can't upgrade.
// ✅ CORRECT on ^6.0.1 — true (or omit; true is the default). Composer clamps
// to viewInsets (ENG-34434), so no double-compensation.
Scaffold(
resizeToAvoidBottomInset: true,
body: Column(
children: [
Expanded(child: CometChatMessageList(user: user)),
CometChatMessageComposer(user: user),
],
),
)
// ⚠ PRE-6.0.1 STOPGAP ONLY — false suppresses the double gap on kits that
// predate the ENG-34434 clamp. Prefer upgrading the kit.
Scaffold(
resizeToAvoidBottomInset: false,
body: Column(
children: [
Expanded(child: CometChatMessageList(user: user)),
CometChatMessageComposer(user: user),
],
),
)
This applies everywhere the composer is used: messages screen, thread screen, or any custom screen.
3.2 Stale user/group data
- Symptom: User name, avatar, or group info doesn't update in real-time. Old data persists even after changes.
- Cause: Passing
widget.userorwidget.groupdirectly to UIKit components instead of maintaining mutable state that updates from listeners. - Fix: Keep mutable
_user/_groupin your State class and update from SDK listeners:
class _MessagesScreenState extends State<MessagesScreen> {
late User? _user;
late Group? _group;
@override
void initState() {
super.initState();
_user = widget.user;
_group = widget.group;
// Register listeners to update _user/_group on changes
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true, // ^6.0.1: composer clamps to viewInsets (ENG-34434)
body: Column(
children: [
Expanded(child: CometChatMessageList(user: _user, group: _group)),
CometChatMessageComposer(user: _user, group: _group),
],
),
);
}
}
3.3 No typing indicators / presence events
- Symptom: Online/offline status never updates. Typing indicators don't appear. No presence events fire. No error is thrown.
- Cause:
subscriptionTypewas not set inUIKitSettingsBuilder. Omitting it silently disables all presence events. - Fix: Always set
subscriptionType:
// ✅ CORRECT
UIKitSettingsBuilder()
..appId = 'APP_ID'
..region = 'us'
..authKey = 'AUTH_KEY'
..subscriptionType = CometChatSubscriptionType.allUsers
// ❌ WRONG — no error, but presence events never fire
UIKitSettingsBuilder()
..appId = 'APP_ID'
..region = 'us'
..authKey = 'AUTH_KEY'
// subscriptionType missing!
3.4 Messages not updating in real-time
- Symptom: New messages don't appear until the screen is refreshed or re-opened.
- Cause: Multiple possible causes:
- SDK message listener not registered (BLoC handles this automatically — check component is mounted)
subscriptionTypenot set (see 3.3)- Component was disposed and listener removed
- Fix:
- Ensure
subscriptionTypeis set in UIKitSettings - Verify the
CometChatMessageListwidget is mounted and not disposed - If using custom BLoC, ensure it registers
CometChat.addMessageListener()in its constructor and removes it inclose()
- Ensure
3.5 Theme jank during keyboard animation
- Symptom: Visible jank (stuttering, dropped frames) when the keyboard opens or closes, especially on message screens.
- Cause: Theme values (
CometChatThemeHelper.getColorPalette(context), etc.) are being looked up insidebuild(). During keyboard animation,MediaQuerychanges trigger rebuilds, and each lookup does expensive InheritedWidget traversal (44–95ms instead of <16ms). - Fix: Cache theme values in
didChangeDependencies()with a_themeInitializedflag:
// ✅ CORRECT — cache once, reuse on every build
class _MyWidgetState extends State<MyWidget> {
late CometChatColorPalette _colorPalette;
late CometChatSpacing _spacing;
late CometChatTypography _typography;
bool _themeInitialized = false;
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (!_themeInitialized) {
_colorPalette = CometChatThemeHelper.getColorPalette(context);
_spacing = CometChatThemeHelper.getSpacing(context);
_typography = CometChatThemeHelper.getTypography(context);
_themeInitialized = true;
}
}
@override
Widget build(BuildContext context) {
// Use _colorPalette, _spacing, _typography — no lookups here
return Container(color: _colorPalette.primary);
}
}
// ❌ WRONG — lookup in build causes jank during keyboard animation
@override
Widget build(BuildContext context) {
final colors = CometChatThemeHelper.getColorPalette(context); // Expensive!
return Container(color: colors.primary);
}
3.6 Extra white space between composer and keyboard
- Symptom: Visible gap between the message composer and the keyboard when it opens.
- Cause: Safe area bottom padding being applied when the keyboard is open. The keyboard already covers the safe area, so adding safe area padding on top creates extra space.
- Fix: Cache
MediaQuery.paddingOf(context).bottomonce indidChangeDependencies(). Never wrap the composer in an extraSafeAreawidget —CometChatMessageComposeralready handles bottom inset internally viaSliverSpacing:
// ✅ CORRECT — cache safe area once, no extra SafeArea wrapper
class _MessagesScreenState extends State<MessagesScreen> {
double _bottomSafeArea = 0;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_bottomSafeArea = MediaQuery.paddingOf(context).bottom;
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true, // ^6.0.1: composer clamps to viewInsets (ENG-34434)
body: Column(
children: [
Expanded(child: CometChatMessageList(user: widget.user)),
CometChatMessageComposer(user: widget.user), // No SafeArea wrapper!
],
),
);
}
}
// ❌ WRONG — SafeArea wrapper adds bottom padding the composer already handles
Scaffold(
resizeToAvoidBottomInset: true,
body: Column(
children: [
Expanded(child: CometChatMessageList(user: widget.user)),
SafeArea( // ← Causes extra white gap when keyboard opens
child: CometChatMessageComposer(user: widget.user),
),
],
),
)
4. Call Issues
4.1 "auth token null" on call init
- Symptom: Calls SDK fails with
auth token nullor similar authentication error when trying to start a call. - Cause: The Calls SDK was initialized before the Chat SDK completed init and login. The Calls SDK needs the auth token from a successful chat login (rule CALLS_INIT_AFTER_CHAT_INIT — see
cometchat-flutter-v6-calls§1.0). - Fix: When
..enableCalls = trueis set onUIKitSettingsBuilder,CallEventServicehandles bothCometChatUIKitCalls.init()andCometChatUIKitCalls.loginWithAuthToken()internally — chat init must complete first. For manual integrations, gate calls init on chat init success:
// ✅ CORRECT — chat init first, calls init in onSuccess
await CometChatUIKit.init(
uiKitSettings: settings,
onSuccess: (_) async {
// For manual calls integration (no ..enableCalls = true):
// CometChatUIKitCalls.init takes raw appId + region STRINGS (not a settings
// builder) and reports via callbacks — verified vs cometchat_uikit_calls.dart:9.
CometChatUIKitCalls.init(
'APP_ID',
'us',
onSuccess: (_) {},
onError: (e) => debugPrint('Calls init failed: $e'),
);
},
onError: (e) => debugPrint('Chat init failed: ${e.message}'),
);
// ❌ WRONG — calls init runs before chat init completes
CometChatUIKit.init(uiKitSettings: settings); // not awaited
await CometChatUIKitCalls.init(callAppSettings); // auth token null
4.2 "session already started"
- Symptom: Error
session already startedwhen trying to join or start a call. - Cause: Two distinct causes — diagnose both:
- Duplicate
CometChatUIKitCalls.init()within one app lifecycle. The Calls SDK is single-init (rule CALL_INIT_ONCE — seecometchat-flutter-v6-calls). Calling init more than once (e.g., from multiple bootstrap paths, hot-restart with stale state) emits this error. - Stale call session from a prior call that was not ended cleanly — user navigated away without hanging up, or the app was killed mid-call.
- Duplicate
- Fix:
// ✅ CAUSE (a) — single-init guard at app boot
bool _callsInitDone = false;
Future<void> initCallsOnce(CallAppSettings settings) async {
if (_callsInitDone) return;
await CometChatUIKitCalls.init(settings);
_callsInitDone = true;
}
// ✅ CAUSE (b) — clean up the stale session via the UIKit-namespaced API.
// The method is endSession (NOT endCall) and takes named callbacks, no sessionId
// — verified vs cometchat_uikit_calls.dart:236.
await CometChatUIKitCalls.endSession(
onSuccess: (_) {},
onError: (e) => debugPrint('endSession failed: $e'),
);
// ❌ WRONG — bare CometChat.endCall is the Chat SDK API, not the calls cleanup
CometChat.endCall(sessionId, onSuccess: ..., onError: ...);
4.3 "CallManager not found" / "Calling module not found"
- Symptom: Android native error
CallManager not foundorCometChat Calling module not found. - Cause: The CometChat Calling native module is not properly linked on Android. This can happen with ProGuard stripping, missing dependencies, or build configuration issues.
- Fix:
- Ensure ProGuard keep rules are in place (see Section 6.1)
- Verify
cometchat_chat_uikitis properly added topubspec.yaml - Run
flutter cleanand rebuild - Check that
android.enableJetifier=trueis ingradle.properties
4.4 "startSession null" on Android
- Symptom:
startSessionreturns null on Android with no error feedback. The call screen may appear blank or stuck. - Cause: Known Android SDK issue where
startSessionsilently fails. A 5-second timeout workaround exists but provides no error feedback. - Fix: This is a known SDK-level issue. Workarounds:
- Implement a timeout wrapper around
startSessioncalls - Show a retry option to the user if the call screen doesn't load within 5 seconds
- Check for updates to
cometchat_calls_sdkthat may fix this
- Implement a timeout wrapper around
4.5 Incoming call not received
- Symptom: Incoming calls are not shown to the receiver. The caller sees the outgoing call screen but the receiver gets nothing.
- Cause: Multiple possible causes:
subscriptionTypenot set (presence/events disabled)- Push notification / VoIP setup incomplete
- Call listeners not registered
- App is in background without proper background handling
- Fix:
- Ensure
subscriptionTypeis set toCometChatSubscriptionType.allUsers - Verify FCM/APNs push notification setup for background calls
- Check that call event listeners are registered
- For cross-platform issues (Android↔iOS↔React), verify all platforms are on compatible SDK versions
- Ensure
4.6 Calls SDK not re-initialized after logout
- Symptom: After logout and re-login, calls don't work. Call screens may be blank or throw errors.
- Cause: The Calls SDK maintains its own session state. After
CometChatUIKit.logout(), the Calls SDK session is invalidated but may not be properly re-initialized on the next login. - Fix: Ensure the Calls SDK is re-initialized after login. The UIKit handles this internally — if you're managing calls manually, call the Calls SDK init after each successful login.
4.7 Outgoing call screen never renders / app shows nothing after tapping call (V6 navigatorKey trap)
- Symptom: Caller taps the call button. The peer rings (server received the call). The caller's Flutter app shows nothing — no outgoing-call screen, no error in
onSuccess/onError.CometChat.initiateCallreturns successfully with a validsessionId, but no UI ever appears. - Cause:
MaterialAppis missingnavigatorKey: CallNavigationContext.navigatorKey. The kit'sCometChatCallButtonsand outgoing-call flow navigate viaCallNavigationContext.navigatorKey.currentContext— which isnulluntil the app'sMaterialAppis wired to that key. The failure is silent becauseinitiateCallitself succeeds; only the navigation to the outgoing-call screen fails. Important: the vendor's own 6.0.1 sample app is missing this line, so customers who copiedmain.dartverbatim will hit this bug. This is the single most common customer-blocking V6 calls trap. - Fix: Wire
CallNavigationContext.navigatorKeyon the rootMaterialApp:
// ✅ CORRECT — navigatorKey wired on MaterialApp
import 'package:flutter/material.dart';
import 'package:cometchat_chat_uikit/cometchat_calls_uikit.dart'
show CallNavigationContext; // calls is a sub-library of cometchat_chat_uikit — there is NO separate cometchat_calls_uikit package in v6
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: CallNavigationContext.navigatorKey, // REQUIRED for V6 calls
home: const HomeScreen(),
);
}
}
// ❌ WRONG — no navigatorKey; outgoing-call screen never appears
return MaterialApp(
home: const HomeScreen(),
);
See cometchat-flutter-v6-calls §1.7 for the canonical wiring rule.
4.8 Stuck on "Calling…" after peer accepts (v6.0.0-beta2 BLoC bug — fixed in 6.0.1)
- Symptom: Outgoing call screen displays correctly, peer accepts the call, but the caller's screen stays stuck on "Calling…" and never transitions to the in-call surface. Audio/video may already be flowing in the background; only the UI state is wrong.
- Cause: A known BLoC transition bug in
cometchat_chat_uikit ^6.0.0-beta2where the outgoing → in-call state never fires. This is FIXED in 6.0.1 GA. - Fix: Upgrade to
cometchat_chat_uikit ^6.0.1(or the latest 6.x):
# pubspec.yaml
dependencies:
cometchat_chat_uikit: ^6.0.1 # was ^6.0.0-beta2
Then run:
flutter pub get
flutter clean
flutter run
If the bug persists after upgrade, verify Section 4.7 (navigatorKey is still required on 6.0.1).
5. Listener Issues
5.1 Duplicate events (hardcoded listener IDs)
- Symptom: Event handlers fire multiple times for a single event. Messages appear twice, typing indicators flicker.
- Cause: Listener registered with a hardcoded ID. When the widget is recreated (e.g., navigation), the new listener overwrites the old one but the old widget's handler may still be referenced, or multiple instances collide.
- Fix: Use a unique listener ID per widget instance:
// ✅ CORRECT — unique ID per instance
class _MyScreenState extends State<MyScreen> with MessageListener {
late final String _listenerId;
@override
void initState() {
super.initState();
_listenerId = 'my_screen_${DateTime.now().millisecondsSinceEpoch}';
CometChat.addMessageListener(_listenerId, this);
}
@override
void dispose() {
CometChat.removeMessageListener(_listenerId);
super.dispose();
}
}
// ❌ WRONG — hardcoded ID causes collisions across instances
CometChat.addMessageListener('messages', this); // Collision!
5.2 Listener leaks (missing dispose)
- Symptom: Memory usage grows over time. Events fire on screens that are no longer visible. App becomes sluggish.
- Cause: SDK listeners registered in
initState()but not removed indispose(). - Fix: Always remove listeners with the same ID used to register:
@override
void dispose() {
CometChat.removeMessageListener(_listenerId);
CometChat.removeUserListener(_listenerId);
CometChat.removeGroupListener(_listenerId);
CometChat.removeCallListener(_listenerId);
super.dispose();
}
5.3 No events firing (subscriptionType not set)
- Symptom: All listeners are properly registered and removed, but no events ever fire. No errors in console.
- Cause:
subscriptionTypenot set inUIKitSettingsBuilder. This silently disables all real-time events. - Fix: Set
subscriptionTypeduring init:
UIKitSettingsBuilder()
..subscriptionType = CometChatSubscriptionType.allUsers
6. Build Errors
6.0 pub get can't resolve cometchat_chat_uikit ^6.x / resolves a beta
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 105
- Forks
- 2
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
cometchat-flutter-v6-troubleshooting- Source
- github.com/cometchat/cometchat-skills