Ground truth — DOCS-FIRST. Push is an EXTERNAL integration (a Firebase project, native config on both platforms, and a Dashboard provider), not a UI Kit widget. The current setup lives in CometChat's notifications docs — FETCH them, via
../cometchat-flutter-v6-core/references/docs-map.md→/notifications/push-overview·/notifications/flutter-push-notifications-android·/notifications/flutter-push-notifications-ios. (The old singular/notifications/flutter-push-notificationsnow redirects to a legacy page — use the per-platform pages above.) This skill bakes ONLY the SDK symbols (verified vscometchat_sdk5.0.6) and the hardening deltas. Symbols baked; the step-by-step is fetched.
Companion skills (read first)
cometchat-flutter-v6-core— install, credentials,init→login→render. This skill ASSUMES it (push registers AFTER login, on the SAME SDK).cometchat-flutter-v6-events— the listener lifecycle; a push registration is a lifecycle-bound side effect.
Use this skill when
"add push notifications", "FCM push", "notify me when the app is closed / backgrounded".
Build it — FETCH the docs, then apply the deltas
- FETCH the setup (source of truth): the notifications docs above. Follow their Firebase project creation,
google-services.json/GoogleService-Info.plistplacement, the Gradle/Podfile changes, and (iOS) the APNs key upload. If the docs are wrong or missing a step, that is a DOCS gap — flag it (RULES.md§20), don't bake a permanent workaround. - Dashboard prerequisite: configure the push provider in the CometChat Dashboard — it is the SENDER. Note the provider ID; registration needs it. Without this, nothing is ever delivered no matter how correct the client is.
- Install:
flutter pub add firebase_core firebase_messaging.CometChatNotificationsships with the already-installedcometchat_sdk— no extra CometChat package.
Baked SDK symbols (verified vs 5.0.6 — do NOT guess these)
dartimport 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart'; // Register AFTER login, with the token you got from firebase_messaging getToken(). Future<void> registerPush(String fcmToken, String providerId) async { await CometChatNotifications.registerPushToken( PushPlatforms.FCM_FLUTTER_ANDROID, // FCM_FLUTTER_IOS on iOS; for a raw APNs token use APNS_FLUTTER_DEVICE / APNS_FLUTTER_VOIP (there is NO plain PushPlatforms.APNS) providerId: providerId, // from the Dashboard provider you configured fcmToken: fcmToken, onSuccess: (res) {}, onError: (e) {}, ); } // On logout — otherwise the device keeps receiving the previous user's messages. Future<void> unregisterPush() async { await CometChatNotifications.unregisterPushToken(onSuccess: (res) {}, onError: (e) {}); }
PushPlatformsis an enum with per-platform Flutter variants — pick the one matching the running platform and the token type (fcmTokenvsdeviceTokenvsvoipToken). Do not pass an FCM token as adeviceToken.
The token lifecycle (the part docs usually under-specify)
- Register AFTER
loginsucceeds — a token registered against no user goes nowhere. - Re-register on token refresh. FCM rotates tokens; listen to
onTokenRefreshand re-register, or delivery silently stops days later. - Unregister on logout, before
CometChatUIKit.logout()— otherwise the next user of that device receives the previous user's notifications. This is a privacy bug, not just a nuisance. - Ask permission at the right moment — iOS (and Android 13+) require a runtime prompt. Request it on a deliberate user action, not at first launch, or users decline permanently.
Common pitfalls (BAKED)
- No Dashboard provider → the client is perfect and nothing is delivered. Check this FIRST when debugging.
- Registering before login → silence.
- Never re-registering on refresh → push works for days, then stops.
- No unregister on logout → the previous user's messages land on the device.
- Testing on a simulator → iOS simulators cannot receive push. Use a real device.
- Expecting push while the app is foregrounded — foreground messages arrive as data; you present them yourself.
- Assuming the web/desktop story matches mobile — verify before promising it.
Verify it works
On a REAL device: permission granted → the token registers after login (no error) → background the app → a message from another user produces a notification → tapping it opens the app → logging out stops delivery to that device. Nothing arriving with a clean client almost always means the Dashboard provider or the platform credential (APNs key / google-services.json), not your Dart.
Live delivery is a manual device check — it cannot be automated here. Say so honestly rather than claiming verification you did not do.

