Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
cometchat avatar

Cometchat Flutter V5 Core

  • 5 installs
  • 70 repo stars
  • Updated June 23, 2026
  • cometchat/cometchat-skills

Hard rules for CometChat Flutter UIKit v5 covering init, login, logout, lifecycle, the GetX pattern, and the two-package import split.

About

Defines non-negotiable constraints for CometChat Flutter UIKit v5 that prevent silent failures and crashes. A developer reads it before writing any v5 Flutter chat code.

  • INIT_FIRST rule: init must complete before login or component use
  • Documents GetX state management and login(uid) taking a String

Cometchat Flutter V5 Core by the numbers

  • 5 all-time installs (skills.sh)
  • Ranked #828 of 1,039 Mobile Development skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/cometchat/cometchat-skills --skill cometchat-flutter-v5-core

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs5
repo stars70
Last updatedJune 23, 2026
Repositorycometchat/cometchat-skills

What it does

Hard rules for CometChat Flutter UIKit v5 covering init, login, logout, lifecycle, the GetX pattern, and the two-package import split.

Files

SKILL.mdMarkdownGitHub ↗

CometChat Flutter UIKit v5 — Core Rules

Non-negotiable constraints for all CometChat UIKit v5 code. Violating these causes silent failures or crashes.

Key v5 Architecture Facts

  • State management: GetX (GetBuilder, GetxController, Get.put, Get.find, Get.delete)
  • Separate packages: cometchat_chat_uikit + cometchat_calls_uikit + cometchat_uikit_shared
  • SDK: cometchat_sdk ^4.1.2 + cometchat_calls_sdk ^4.2.2
  • Imports — two barrels. For chat-only projects: package:cometchat_chat_uikit/cometchat_chat_uikit.dart. For projects that also need voice/video calling: ADD package:cometchat_calls_uikit/cometchat_calls_uikit.dart as a SECOND import — the calls barrel re-exports shared + SDK only and does NOT re-export cometchat_chat_uikit. Chat widgets like CometChatConversations, CometChatMessageList, CometChatMessageComposer are reachable only through the chat barrel.
  • CometChatUIKit.login(uid) takes a String directly (not an object)
  • No ServiceLocator pattern — controllers are created via Get.put() internally
  • Style classes use ThemeExtension with merge() pattern

Rule: INIT_FIRST

CometChatUIKit.init() must complete before any login, component usage, or SDK call.

// ✅ CORRECT
final settings = (UIKitSettingsBuilder()
      ..appId = 'APP_ID'
      ..region = 'us'
      ..authKey = 'AUTH_KEY'
      ..subscriptionType = CometChatSubscriptionType.allUsers)
    .build();

CometChatUIKit.init(
  uiKitSettings: settings,
  onSuccess: (_) => debugPrint('Init done'),
  onError: (e) => debugPrint('Init failed: ${e.message}'),
);

// ❌ WRONG — login before init completes
CometChatUIKit.init(uiKitSettings: settings);
CometChatUIKit.login('uid'); // Race condition

Rule: AUTH_CHECK_AFTER_INIT

After CometChatUIKit.init() completes, the static field CometChatUIKit.loggedInUser is populated if a cached session exists (init internally calls getLoggedInUser()). You can check it synchronously in onSuccess, or use CometChatUIKit.getLoggedInUser() for an explicit async check.

// ✅ CORRECT — synchronous check after init
CometChatUIKit.init(
  uiKitSettings: settings,
  onSuccess: (_) {
    final hasUser = CometChatUIKit.loggedInUser != null;
    // Route to home or login
  },
);

// ✅ ALSO CORRECT — explicit async check (used by master app)
CometChatUIKit.init(
  uiKitSettings: settings,
  onSuccess: (_) async {
    final user = await CometChatUIKit.getLoggedInUser();
    if (user != null) {
      await CometChatUIKit.login(user.uid, onSuccess: ...);
    }
  },
);

Note: CometChatUIKit.login() handles re-login gracefully — if the user is already logged in with the same UID, it returns the cached user without hitting the server.

Rule: LISTENER_LIFECYCLE

SDK listeners MUST be registered with a unique ID in initState() (or GetxController onInit()) and removed in dispose() (or onClose()).

// ✅ CORRECT
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; missing dispose removal
CometChat.addMessageListener('messages', this); // Collision!

Rule: THEME_CACHE

Cache theme values in didChangeDependencies() — unconditionally, no flag needed. Never call CometChatThemeHelper.getColorPalette(context) in build().

getColorPalette() creates a new CometChatColorPalette object every call, resolving each token individually via Theme.of(context). During keyboard animation, MediaQuery changes trigger rebuilds, making this expensive in build().

// ✅ CORRECT — matches actual package pattern (no flag)
@override
void didChangeDependencies() {
  super.didChangeDependencies();
  colorPalette = CometChatThemeHelper.getColorPalette(context);
  spacing = CometChatThemeHelper.getSpacing(context);
  typography = CometChatThemeHelper.getTypography(context);
}

// ❌ WRONG — lookup in build causes jank
@override
Widget build(BuildContext context) {
  final colors = CometChatThemeHelper.getColorPalette(context); // Expensive!
  return Container(color: colors.primary);
}

Do NOT use a _themeInitialized flag — it prevents theme updates when the system switches between light/dark mode.

Rule: SUBSCRIPTION_TYPE_REQUIRED

Omitting subscriptionType in UIKitSettingsBuilder silently disables all presence events (online/offline, typing indicators). No error is thrown.

// ✅ CORRECT
UIKitSettingsBuilder()
  ..subscriptionType = CometChatSubscriptionType.allUsers

Rule: REGION_LOWERCASE

Region must be a lowercase string: 'us', 'eu', or 'in'.

Rule: MUID_PRESERVATION

When handling ccMessageSent events, compare by muid first, then id — the SDK may return an empty muid in the success callback.

Pattern: Callback → Async Bridge (Completer)

import 'dart:async';

Future<bool> initAsync(UIKitSettings settings) {
  final completer = Completer<bool>();
  CometChatUIKit.init(
    uiKitSettings: settings,
    onSuccess: (_) => completer.complete(true),
    onError: (e) => completer.complete(false),
  );
  return completer.future;
}

v5 Component Architecture Pattern (GetX)

{component}/
├── cometchat_{component}.dart              # StatefulWidget
├── cometchat_{component}_controller.dart   # extends GetxController
├── cometchat_{component}_style.dart        # ThemeExtension with merge()
└── {component}_builder_protocol.dart       # Request builder protocol

Internal lifecycle:

@override
void initState() {
  super.initState();
  tag = widget.controllerTag ?? 'default_tag_${DateTime.now().millisecondsSinceEpoch}';
  controller = Get.put<Controller>(Controller(...), tag: tag);
}

@override
void dispose() {
  if (widget.controllerTag == null) {
    Get.delete<Controller>(tag: tag);
  }
  super.dispose();
}

Android Build Requirements

  • android.useAndroidX=true and android.enableJetifier=true in gradle.properties
  • minSdk 26 in android/app/build.gradle
  • ProGuard: -keep class com.cometchat.** { *; } and -keep interface com.cometchat.** { *; }

Top 10 Error Debugging

SymptomCauseFix
"Authentication null"CometChatUIKit.init() not calledCall init before login/components
"APP ID null"appId not set in UIKitSettingsBuilderSet ..appId = 'YOUR_APP_ID'
No typing indicators / presencesubscriptionType not setSet ..subscriptionType = CometChatSubscriptionType.allUsers
Theme jank during keyboardTheme looked up in build()Cache in didChangeDependencies()
Listener leak / duplicate eventsListener not removed in dispose()Always remove with same ID
GetX controller not foundUsing Get.find() before Get.put()Let UIKit components manage their own controllers
Region errorUppercase region stringUse lowercase: 'us', 'eu', 'in'
Release build crashMissing ProGuard keep rulesAdd -keep class com.cometchat.** { *; }

Checklist — Every CometChat v5 Screen

  • [ ] CometChatUIKit.init() called before any usage
  • [ ] subscriptionType set in UIKitSettingsBuilder
  • [ ] region is lowercase
  • [ ] Theme cached in didChangeDependencies(), not build()
  • [ ] SDK listeners registered with unique ID, removed in dispose()
  • [ ] Colors from CometChatThemeHelper, never hardcoded
  • [ ] Imports: package:cometchat_chat_uikit/cometchat_chat_uikit.dart always; ADD package:cometchat_calls_uikit/cometchat_calls_uikit.dart if you use voice/video

Visual Builder integration

Flutter V5 is the primary home for Visual Builder integration. The canonical repo at the chat_builder/ directory inside the Flutter Visual Builder ZIP (download from https://preview.cometchat.com/downloads/cometchat-builder-flutter.zip) ships V5-shaped codecometchat_chat_uikit: ^5.2.12 + cometchat_calls_uikit: ^5.0.13. The integration copies the entire chat_builder/ directory as a path: dependency, then BuilderSettingsHelper.loadFromAsset() reads chat_builder/assets/sample_app/cometchat-builder-settings.json and configures the bundled chat UI accordingly.

The full recipe lives in `cometchat-flutter-v6-core` §"Visual Builder integration" because that's where the V6-prep restructure originally landed the validated content. Both skills reference the same canonical; the V6 page carries a "V5-shaped code" warning at the top. V5 customers should follow that recipe AS-IS — the canonical IS V5-targeted.

Validated 2026-05-21 against Flutter 3.38.3: flutter build apk --debug produces app-debug.apk after applying:

  • Envelope-wrapped JSON at chat_builder/assets/sample_app/cometchat-builder-settings.json ({ builderId, name, settings: {...} })
  • Two missing-field defaults injected pre-write (mentionAll + inAppSounds — same as Android)
  • android.enableJetifier=true in android/gradle.properties (the chat SDK pulls com.android.support transitively)
  • await BuilderSettingsHelper.loadFromAsset() in lib/main.dart before runApp()
  • chat_builder: { path: ./chat_builder } in host pubspec.yaml

Differences from the V6 page's recipe text:

  • V5 host code uses StatefulWidget with direct listener management (V6 uses BLoC pattern); both work with the embedded chat_builder package since it owns its own state.
  • V5 calls work via the standard cometchat-flutter-v5-calls flow — no [[project_v6_flutter_calls_partial]] navigatorKey workaround needed (that's a V6-beta-specific issue).

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.