cometchat-flutter-v6-events — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited cometchat-flutter-v6-events (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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.
Two event systems: SDK listeners (from CometChat server) and UI events (from UIKit components).
Register on CometChat SDK directly. These fire when the server pushes real-time data.
| Listener Mixin | Register / Remove | Key Callbacks |
|---|---|---|
MessageListener | CometChat.addMessageListener(id, this) / removeMessageListener(id) | onTextMessageReceived, onMediaMessageReceived, onCustomMessageReceived, onTypingStarted, onTypingEnded, onMessagesDelivered, onMessagesRead, onMessageEdited, onMessageDeleted |
UserListener | CometChat.addUserListener(id, this) / removeUserListener(id) | onUserOnline, onUserOffline |
GroupListener | CometChat.addGroupListener(id, this) / removeGroupListener(id) | onGroupMemberJoined, onGroupMemberLeft, onGroupMemberKicked, onGroupMemberBanned, onGroupMemberScopeChanged, onMemberAddedToGroup |
CallListener | CometChat.addCallListener(id, this) / removeCallListener(id) | onIncomingCallReceived, onOutgoingCallAccepted, onOutgoingCallRejected, onIncomingCallCancelled |
ConnectionListener | CometChat.addConnectionListener(id, this) / removeConnectionListener(id) | onConnected, onDisconnected, onConnecting, onFeatureThrottled |
class _MyScreenState extends State<MyScreen>
with MessageListener, UserListener {
late final String _listenerId;
@override
void initState() {
super.initState();
_listenerId = 'my_screen_${DateTime.now().millisecondsSinceEpoch}';
CometChat.addMessageListener(_listenerId, this);
CometChat.addUserListener(_listenerId, this);
}
@override
void dispose() {
CometChat.removeMessageListener(_listenerId);
CometChat.removeUserListener(_listenerId);
super.dispose();
}
@override
void onTextMessageReceived(TextMessage message) {
// Handle incoming text message
}
@override
void onUserOnline(User user) {
// Handle user coming online
}
@override
void onUserOffline(User user) {
// Handle user going offline
}
}These fire when UIKit components perform actions. Use these to react to user interactions across components.
// Listen
CometChatMessageEvents.addMessagesListener('my_listener', MyMessageEventListener());
// Remove
CometChatMessageEvents.removeMessagesListener('my_listener');
// Key callbacks in CometChatMessageEventListener:
// ccMessageSent(BaseMessage message, MessageStatus status) — inProgress/sent/error
// ccMessageEdited(BaseMessage message, MessageEditStatus status)
// ccMessageDeleted(BaseMessage message, EventStatus status)
// ccMessageRead(BaseMessage message)
// ccLiveReaction(String reaction)CometChatUserEvents.addUsersListener('my_listener', MyUserEventListener());
CometChatUserEvents.removeUsersListener('my_listener');
// Key callbacks:
// ccUserBlocked(User user)
// ccUserUnblocked(User user)CometChatGroupEvents.addGroupsListener('my_listener', MyGroupEventListener());
CometChatGroupEvents.removeGroupsListener('my_listener');
// Key callbacks:
// ccGroupMemberKicked(Action, User kickedUser, User kickedBy, Group)
// ccGroupMemberBanned(Action, User bannedUser, User bannedBy, Group)
// ccGroupMemberScopeChanged(Action, User updatedUser, String newScope, String oldScope, Group)
// ccGroupCreated(Group)
// ccGroupDeleted(Group)
// ccGroupLeft(Action, User, Group)
// ccOwnershipChanged(Group, GroupMember)CometChatConversationEvents.addConversationListListener('my_listener', MyConvListener());
CometChatConversationEvents.removeConversationListListener('my_listener');
// Key callbacks:
// ccConversationDeleted(Conversation)| Scenario | Use |
|---|---|
| Incoming message from another user | SDK MessageListener.onTextMessageReceived |
| Current user sent a message via composer | UI CometChatMessageEvents.ccMessageSent |
| Another user comes online | SDK UserListener.onUserOnline |
| Current user blocked someone via UIKit | UI CometChatUserEvents.ccUserBlocked |
| Group member kicked by another admin | SDK GroupListener.onGroupMemberKicked |
| Current user kicked someone via UIKit | UI CometChatGroupEvents.ccGroupMemberKicked |
Key distinction: SDK listeners fire for remote events. UI events fire for local user actions performed through UIKit components.
The 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.
Register your own listeners only when you need to:
Called automatically by CometChatUIKit._initiateAfterLogin(). Bridges SDK events to UIKit's internal event bus. You never need to call this manually.
onTypingStarted/onTypingEnded only fire if subscriptionType was set in UIKitSettings. Omitting it silently disables all presence/typing events.compute() if needed.ccMessageSent fires three times per message: once with MessageStatus.inProgress, once with MessageStatus.sent (success), or once with MessageStatus.error (failure). Filter by status.onConnected fires on reconnect — use it to trigger a silent refresh of your data.Action object (which is a BaseMessage subclass). Don't confuse it with the Action widget from Flutter.// ❌ WRONG — hardcoded listener ID causes silent overwrite
CometChat.addMessageListener('messages', this);
// Later, another screen does the same:
CometChat.addMessageListener('messages', this); // First listener silently lost!
// ✅ CORRECT — unique ID per instance
final id = 'screen_${DateTime.now().millisecondsSinceEpoch}';
CometChat.addMessageListener(id, this);// ❌ WRONG — registering SDK listeners for a UIKit component you're already using
// ConversationsBloc already handles MessageListener, UserListener, GroupListener internally
CometChat.addMessageListener('redundant', this); // Duplicate handling
// ✅ CORRECT — only register for custom logic outside UIKit components
// Let ConversationsBloc handle its own listeners// ❌ WRONG — not filtering ccMessageSent status
void onCcMessageSent(BaseMessage msg, MessageStatus status) {
addToList(msg); // Adds 3 times! (inProgress + sent + error)
}
// ✅ CORRECT — filter by status
void onCcMessageSent(BaseMessage msg, MessageStatus status) {
if (status == MessageStatus.sent) {
addToList(msg);
}
}initState() are removed in dispose()subscriptionType set in UIKitSettings for presence/typing eventsccMessageSent handlers filter by MessageStatusAction 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)~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.