{"id":"8960ea0f-8617-4c66-adf0-b036ea8728ef","shortId":"nQsmnX","kind":"skill","title":"cometchat-flutter-v6-events","tagline":"Use when working with real-time events, SDK listeners, or UI event streams in CometChat Flutter UIKit v6. Triggers on mentions of CometChatMessageEvents, CometChatUserEvents, CometChatGroupEvents, CometChatCallEvents, CometChatConversationEvents, MessageListener, UserListener, Gr","description":"# CometChat Flutter UIKit — Events & Listeners\n\nTwo event systems: SDK listeners (from CometChat server) and UI events (from UIKit components).\n\n## SDK Listeners (Server → App)\n\nRegister on CometChat SDK directly. These fire when the server pushes real-time data.\n\n### Available Listener Types\n\n| Listener Mixin | Register / Remove | Key Callbacks |\n|----------------|-------------------|---------------|\n| `MessageListener` | `CometChat.addMessageListener(id, this)` / `removeMessageListener(id)` | `onTextMessageReceived`, `onMediaMessageReceived`, `onCustomMessageReceived`, `onTypingStarted`, `onTypingEnded`, `onMessagesDelivered`, `onMessagesRead`, `onMessageEdited`, `onMessageDeleted` |\n| `UserListener` | `CometChat.addUserListener(id, this)` / `removeUserListener(id)` | `onUserOnline`, `onUserOffline` |\n| `GroupListener` | `CometChat.addGroupListener(id, this)` / `removeGroupListener(id)` | `onGroupMemberJoined`, `onGroupMemberLeft`, `onGroupMemberKicked`, `onGroupMemberBanned`, `onGroupMemberScopeChanged`, `onMemberAddedToGroup` |\n| `CallListener` | `CometChat.addCallListener(id, this)` / `removeCallListener(id)` | `onIncomingCallReceived`, `onOutgoingCallAccepted`, `onOutgoingCallRejected`, `onIncomingCallCancelled` |\n| `ConnectionListener` | `CometChat.addConnectionListener(id, this)` / `removeConnectionListener(id)` | `onConnected`, `onDisconnected`, `onConnecting`, `onFeatureThrottled` |\n\n### Registration Pattern\n\n```dart\nclass _MyScreenState extends State<MyScreen>\n    with MessageListener, UserListener {\n  late final String _listenerId;\n\n  @override\n  void initState() {\n    super.initState();\n    _listenerId = 'my_screen_${DateTime.now().millisecondsSinceEpoch}';\n    CometChat.addMessageListener(_listenerId, this);\n    CometChat.addUserListener(_listenerId, this);\n  }\n\n  @override\n  void dispose() {\n    CometChat.removeMessageListener(_listenerId);\n    CometChat.removeUserListener(_listenerId);\n    super.dispose();\n  }\n\n  @override\n  void onTextMessageReceived(TextMessage message) {\n    // Handle incoming text message\n  }\n\n  @override\n  void onUserOnline(User user) {\n    // Handle user coming online\n  }\n\n  @override\n  void onUserOffline(User user) {\n    // Handle user going offline\n  }\n}\n```\n\n## UI Events (UIKit Component → App)\n\nThese fire when UIKit components perform actions. Use these to react to user interactions across components.\n\n### CometChatMessageEvents\n\n```dart\n// Listen\nCometChatMessageEvents.addMessagesListener('my_listener', MyMessageEventListener());\n\n// Remove\nCometChatMessageEvents.removeMessagesListener('my_listener');\n\n// Key callbacks in CometChatMessageEventListener:\n// ccMessageSent(BaseMessage message, MessageStatus status)  — inProgress/sent/error\n// ccMessageEdited(BaseMessage message, MessageEditStatus status)\n// ccMessageDeleted(BaseMessage message, EventStatus status)\n// ccMessageRead(BaseMessage message)\n// ccLiveReaction(String reaction)\n```\n\n### CometChatUserEvents\n\n```dart\nCometChatUserEvents.addUsersListener('my_listener', MyUserEventListener());\nCometChatUserEvents.removeUsersListener('my_listener');\n\n// Key callbacks:\n// ccUserBlocked(User user)\n// ccUserUnblocked(User user)\n```\n\n### CometChatGroupEvents\n\n```dart\nCometChatGroupEvents.addGroupsListener('my_listener', MyGroupEventListener());\nCometChatGroupEvents.removeGroupsListener('my_listener');\n\n// Key callbacks:\n// ccGroupMemberKicked(Action, User kickedUser, User kickedBy, Group)\n// ccGroupMemberBanned(Action, User bannedUser, User bannedBy, Group)\n// ccGroupMemberScopeChanged(Action, User updatedUser, String newScope, String oldScope, Group)\n// ccGroupCreated(Group)\n// ccGroupDeleted(Group)\n// ccGroupLeft(Action, User, Group)\n// ccOwnershipChanged(Group, GroupMember)\n```\n\n### CometChatConversationEvents\n\n```dart\nCometChatConversationEvents.addConversationListListener('my_listener', MyConvListener());\nCometChatConversationEvents.removeConversationListListener('my_listener');\n\n// Key callbacks:\n// ccConversationDeleted(Conversation)\n```\n\n## SDK vs UI Events — When to Use Which\n\n| Scenario | Use |\n|----------|-----|\n| Incoming message from another user | SDK `MessageListener.onTextMessageReceived` |\n| Current user sent a message via composer | UI `CometChatMessageEvents.ccMessageSent` |\n| Another user comes online | SDK `UserListener.onUserOnline` |\n| Current user blocked someone via UIKit | UI `CometChatUserEvents.ccUserBlocked` |\n| Group member kicked by another admin | SDK `GroupListener.onGroupMemberKicked` |\n| Current user kicked someone via UIKit | UI `CometChatGroupEvents.ccGroupMemberKicked` |\n\nKey distinction: SDK listeners fire for remote events. UI events fire for local user actions performed through UIKit components.\n\n## BLoC Components Handle Listeners Automatically\n\nThe UIKit BLoCs (`ConversationsBloc`, `MessageListBloc`, etc.) register all necessary SDK listeners internally. You do NOT need to register listeners for components you're using — they handle their own real-time updates.\n\nRegister your own listeners only when you need to:\n- Update custom UI outside UIKit components\n- Track events for analytics\n- Sync state between screens\n\n## ChatSDKEventInitializer\n\nCalled automatically by `CometChatUIKit._initiateAfterLogin()`. Bridges SDK events to UIKit's internal event bus. You never need to call this manually.\n\n## Gotchas\n\n- Listener IDs MUST be unique per registration. Using the same ID overwrites the previous listener silently — no error thrown, old listener just stops receiving events.\n- `onTypingStarted`/`onTypingEnded` only fire if `subscriptionType` was set in `UIKitSettings`. Omitting it silently disables all presence/typing events.\n- SDK listeners fire on the main isolate. Heavy processing in callbacks blocks the UI thread. Offload to `compute()` if needed.\n- `ccMessageSent` fires three times per message: once with `MessageStatus.inProgress`, once with `MessageStatus.sent` (success), or once with `MessageStatus.error` (failure). Filter by status.\n- Connection listener's `onConnected` fires on reconnect — use it to trigger a silent refresh of your data.\n- Group listener callbacks include an `Action` object (which is a `BaseMessage` subclass). Don't confuse it with the `Action` widget from Flutter.\n\n## Anti-Patterns\n\n```dart\n// ❌ WRONG — hardcoded listener ID causes silent overwrite\nCometChat.addMessageListener('messages', this);\n// Later, another screen does the same:\nCometChat.addMessageListener('messages', this); // First listener silently lost!\n\n// ✅ CORRECT — unique ID per instance\nfinal id = 'screen_${DateTime.now().millisecondsSinceEpoch}';\nCometChat.addMessageListener(id, this);\n```\n\n```dart\n// ❌ WRONG — registering SDK listeners for a UIKit component you're already using\n// ConversationsBloc already handles MessageListener, UserListener, GroupListener internally\nCometChat.addMessageListener('redundant', this); // Duplicate handling\n\n// ✅ CORRECT — only register for custom logic outside UIKit components\n// Let ConversationsBloc handle its own listeners\n```\n\n```dart\n// ❌ WRONG — not filtering ccMessageSent status\nvoid onCcMessageSent(BaseMessage msg, MessageStatus status) {\n  addToList(msg); // Adds 3 times! (inProgress + sent + error)\n}\n\n// ✅ CORRECT — filter by status\nvoid onCcMessageSent(BaseMessage msg, MessageStatus status) {\n  if (status == MessageStatus.sent) {\n    addToList(msg);\n  }\n}\n```\n\n## Checklist\n\n- [ ] Listener IDs are unique (use timestamp or UUID suffix)\n- [ ] All listeners registered in `initState()` are removed in `dispose()`\n- [ ] `subscriptionType` set in UIKitSettings for presence/typing events\n- [ ] `ccMessageSent` handlers filter by `MessageStatus`\n- [ ] No redundant listeners for UIKit components that handle their own\n- [ ] `Action` from CometChat SDK not confused with Flutter's `Action` widget (use `import 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart' as cc;` and `cc.Action`)","tags":["cometchat","flutter","events","skills","agent-skills","ai-agent","chat","claude-code","cursor","messaging","nextjs","react"],"capabilities":["skill","source-cometchat","skill-cometchat-flutter-v6-events","topic-agent-skills","topic-ai-agent","topic-chat","topic-claude-code","topic-cometchat","topic-cursor","topic-messaging","topic-nextjs","topic-react","topic-react-native","topic-ui-kit"],"categories":["cometchat-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cometchat/cometchat-skills/cometchat-flutter-v6-events","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cometchat/cometchat-skills","source_repo":"https://github.com/cometchat/cometchat-skills","install_from":"skills.sh"}},"qualityScore":"0.463","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 27 github stars · SKILL.md body (7,885 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:04:51.475Z","embedding":null,"createdAt":"2026-05-07T13:05:11.337Z","updatedAt":"2026-05-18T19:04:51.475Z","lastSeenAt":"2026-05-18T19:04:51.475Z","tsv":"'3':710 'across':222 'action':214,290,297,304,317,406,598,611,771,780 'add':709 'addtolist':707,728 'admin':381 'alreadi':666,669 'analyt':466 'anoth':349,362,380,630 'anti':616 'anti-pattern':615 'app':59,207 'automat':415,473 'avail':75 'bannedbi':301 'bannedus':299 'basemessag':240,246,251,256,603,703,721 'bloc':411,418 'block':370,546 'bridg':476 'bus':484 'call':472,489 'callback':83,236,271,288,333,545,595 'calllisten':119 'caus':623 'cc':789 'cc.action':791 'ccconversationdelet':334 'ccgroupcreat':312 'ccgroupdelet':314 'ccgroupleft':316 'ccgroupmemberban':296 'ccgroupmemberkick':289 'ccgroupmemberscopechang':303 'cclivereact':258 'ccmessagedelet':250 'ccmessageedit':245 'ccmessageread':255 'ccmessages':239,555,699,756 'ccownershipchang':320 'ccuserblock':272 'ccuserunblock':275 'chat':786 'chatsdkeventiniti':471 'checklist':730 'class':142 'come':192,364 'cometchat':2,21,37,48,62,773,785 'cometchat-flutter-v6-events':1 'cometchat.addcalllistener':120 'cometchat.addconnectionlistener':130 'cometchat.addgrouplistener':108 'cometchat.addmessagelistener':85,162,626,635,652,675 'cometchat.adduserlistener':100,165 'cometchat.removemessagelistener':171 'cometchat.removeuserlistener':173 'cometchatcallev':32 'cometchatconversationev':33,323 'cometchatconversationevents.addconversationlistlistener':325 'cometchatconversationevents.removeconversationlistlistener':329 'cometchatgroupev':31,278 'cometchatgroupevents.addgroupslistener':280 'cometchatgroupevents.ccgroupmemberkicked':391 'cometchatgroupevents.removegroupslistener':284 'cometchatmessageev':29,224 'cometchatmessageeventlisten':238 'cometchatmessageevents.addmessageslistener':227 'cometchatmessageevents.ccmessagesent':361 'cometchatmessageevents.removemessageslistener':232 'cometchatuikit._initiateafterlogin':475 'cometchatuserev':30,261 'cometchatuserevents.adduserslistener':263 'cometchatuserevents.ccuserblocked':375 'cometchatuserevents.removeuserslistener':267 'compon':55,206,212,223,410,412,436,462,663,688,766 'compos':359 'comput':552 'confus':607,776 'connect':576 'connectionlisten':129 'convers':335 'conversationsbloc':419,668,690 'correct':642,680,715 'current':353,368,384 'custom':458,684 'dart':141,225,262,279,324,618,655,695 'data':74,592 'datetime.now':160,650 'direct':64 'disabl':531 'dispos':170,748 'distinct':393 'duplic':678 'error':510,714 'etc':421 'event':5,13,18,40,43,52,204,339,399,401,464,478,483,517,534,755 'eventstatus':253 'extend':144 'failur':572 'filter':573,698,716,758 'final':150,647 'fire':66,209,396,402,521,537,556,580 'first':638 'flutter':3,22,38,614,778 'go':201 'gotcha':492 'gr':36 'group':295,302,311,313,315,319,321,376,593 'grouplisten':107,673 'grouplistener.ongroupmemberkicked':383 'groupmemb':322 'handl':181,190,199,413,441,670,679,691,768 'handler':757 'hardcod':620 'heavi':542 'id':86,89,101,104,109,112,121,124,131,134,494,503,622,644,648,653,732 'import':783 'includ':596 'incom':182,346 'initst':155,744 'inprogress':712 'inprogress/sent/error':244 'instanc':646 'interact':221 'intern':427,482,674 'isol':541 'key':82,235,270,287,332,392 'kick':378,386 'kickedbi':294 'kickedus':292 'late':149 'later':629 'let':689 'listen':15,41,46,57,76,78,226,229,234,265,269,282,286,327,331,395,414,426,434,451,493,507,513,536,577,594,621,639,659,694,731,741,763 'listenerid':152,157,163,166,172,174 'local':404 'logic':685 'lost':641 'main':540 'manual':491 'member':377 'mention':27 'messag':180,184,241,247,252,257,347,357,560,627,636 'messageeditstatus':248 'messagelistbloc':420 'messagelisten':34,84,147,671 'messagelistener.ontextmessagereceived':352 'messagestatus':242,705,723,760 'messagestatus.error':571 'messagestatus.inprogress':563 'messagestatus.sent':566,727 'millisecondssinceepoch':161,651 'mixin':79 'msg':704,708,722,729 'must':495 'myconvlisten':328 'mygroupeventlisten':283 'mymessageeventlisten':230 'myscreenst':143 'myusereventlisten':266 'necessari':424 'need':431,455,487,554 'never':486 'newscop':308 'object':599 'offlin':202 'offload':550 'old':512 'oldscop':310 'omit':528 'onccmessages':702,720 'onconnect':135,137,579 'oncustommessagereceiv':92 'ondisconnect':136 'onfeaturethrottl':138 'ongroupmemberban':116 'ongroupmemberjoin':113 'ongroupmemberkick':115 'ongroupmemberleft':114 'ongroupmemberscopechang':117 'onincomingcallcancel':128 'onincomingcallreceiv':125 'onlin':193,365 'onmediamessagereceiv':91 'onmemberaddedtogroup':118 'onmessagedelet':98 'onmessageedit':97 'onmessagesdeliv':95 'onmessagesread':96 'onoutgoingcallaccept':126 'onoutgoingcallreject':127 'ontextmessagereceiv':90,178 'ontypingend':94,519 'ontypingstart':93,518 'onuserofflin':106,196 'onuseronlin':105,187 'outsid':460,686 'overrid':153,168,176,185,194 'overwrit':504,625 'packag':784 'pattern':140,617 'per':498,559,645 'perform':213,407 'presence/typing':533,754 'previous':506 'process':543 'push':70 're':438,665 'react':218 'reaction':260 'real':11,72,445 'real-tim':10,71,444 'receiv':516 'reconnect':582 'redund':676,762 'refresh':589 'regist':60,80,422,433,448,657,682,742 'registr':139,499 'remot':398 'remov':81,231,746 'removecalllisten':123 'removeconnectionlisten':133 'removegrouplisten':111 'removemessagelisten':88 'removeuserlisten':103 'scenario':344 'screen':159,470,631,649 'sdk':14,45,56,63,336,351,366,382,394,425,477,535,658,774 'sent':355,713 'server':49,58,69 'set':525,750 'silent':508,530,588,624,640 'skill' 'skill-cometchat-flutter-v6-events' 'someon':371,387 'source-cometchat' 'state':145,468 'status':243,249,254,575,700,706,718,724,726 'stop':515 'stream':19 'string':151,259,307,309 'subclass':604 'subscriptiontyp':523,749 'success':567 'suffix':739 'super.dispose':175 'super.initstate':156 'sync':467 'system':44 'text':183 'textmessag':179 'thread':549 'three':557 'thrown':511 'time':12,73,446,558,711 'timestamp':736 'topic-agent-skills' 'topic-ai-agent' 'topic-chat' 'topic-claude-code' 'topic-cometchat' 'topic-cursor' 'topic-messaging' 'topic-nextjs' 'topic-react' 'topic-react-native' 'topic-ui-kit' 'track':463 'trigger':25,586 'two':42 'type':77 'ui':17,51,203,338,360,374,390,400,459,548 'uikit':23,39,54,205,211,373,389,409,417,461,480,662,687,765 'uikit/cometchat_chat_uikit.dart':787 'uikitset':527,752 'uniqu':497,643,734 'updat':447,457 'updatedus':306 'use':6,215,342,345,439,500,583,667,735,782 'user':188,189,191,197,198,200,220,273,274,276,277,291,293,298,300,305,318,350,354,363,369,385,405 'userlisten':35,99,148,672 'userlistener.onuseronline':367 'uuid':738 'v6':4,24 'via':358,372,388 'void':154,169,177,186,195,701,719 'vs':337 'widget':612,781 'work':8 'wrong':619,656,696","prices":[{"id":"c796a53c-c3ef-4ae7-bbbc-593665a657d0","listingId":"8960ea0f-8617-4c66-adf0-b036ea8728ef","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cometchat","category":"cometchat-skills","install_from":"skills.sh"},"createdAt":"2026-05-07T13:05:11.337Z"}],"sources":[{"listingId":"8960ea0f-8617-4c66-adf0-b036ea8728ef","source":"github","sourceId":"cometchat/cometchat-skills/cometchat-flutter-v6-events","sourceUrl":"https://github.com/cometchat/cometchat-skills/tree/main/skills/cometchat-flutter-v6-events","isPrimary":false,"firstSeenAt":"2026-05-07T13:05:11.337Z","lastSeenAt":"2026-05-18T19:04:51.475Z"}],"details":{"listingId":"8960ea0f-8617-4c66-adf0-b036ea8728ef","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cometchat","slug":"cometchat-flutter-v6-events","github":{"repo":"cometchat/cometchat-skills","stars":27,"topics":["agent-skills","ai-agent","chat","claude-code","cometchat","cursor","messaging","nextjs","react","react-native","ui-kit"],"license":null,"html_url":"https://github.com/cometchat/cometchat-skills","pushed_at":"2026-05-18T05:04:24Z","description":"Add CometChat chat to any React, Next.js, React Native, Angular, Android, iOS, or Flutter project through your AI coding agent. Works with Claude Code, Cursor, Codex, VS Code Copilot, Windsurf, Cline, Kiro, and 50+ more agents.","skill_md_sha":"b95e70b4daa6f81ee1da036750f005e9bd05d81a","skill_md_path":"skills/cometchat-flutter-v6-events/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cometchat/cometchat-skills/tree/main/skills/cometchat-flutter-v6-events"},"layout":"multi","source":"github","category":"cometchat-skills","frontmatter":{"name":"cometchat-flutter-v6-events","license":"MIT","description":"Use when working with real-time events, SDK listeners, or UI event streams in CometChat Flutter UIKit v6. Triggers on mentions of CometChatMessageEvents, CometChatUserEvents, CometChatGroupEvents, CometChatCallEvents, CometChatConversationEvents, MessageListener, UserListener, GroupListener, CallListener, ConnectionListener, ccMessageSent, ccMessageEdited, ccMessageDeleted, ccUserBlocked, ccUserUnblocked, ccGroupMemberKicked, ccGroupMemberBanned, onMessageReceived, onTypingStarted, onTypingEnded, onUserOnline, onUserOffline, onMessageDelivered, onMessageRead, addMessageListener, removeMessageListener, ChatSDKEventInitializer, or any real-time update handling in CometChat.","compatibility":"cometchat_chat_uikit ^6.0.0-beta2; cometchat_sdk ^4.1.2"},"skills_sh_url":"https://skills.sh/cometchat/cometchat-skills/cometchat-flutter-v6-events"},"updatedAt":"2026-05-18T19:04:51.475Z"}}