@cometchat/skills 4.3.0 → 4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/bin/install.js +27 -0
- package/package.json +14 -1
- package/skills/cometchat/SKILL.md +233 -69
- package/skills/cometchat/references/asking-questions.md +48 -0
- package/skills/cometchat-a11y/SKILL.md +3 -2
- package/skills/cometchat-android-v5/SKILL.md +2 -1
- package/skills/cometchat-android-v5-calls/SKILL.md +36 -22
- package/skills/cometchat-android-v5-calls/references/README.md +1 -1
- package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +7 -5
- package/skills/cometchat-android-v5-calls/references/audio-controls.md +4 -4
- package/skills/cometchat-android-v5-calls/references/call-layouts.md +33 -25
- package/skills/cometchat-android-v5-calls/references/call-session.md +2 -2
- package/skills/cometchat-android-v5-calls/references/custom-ui.md +5 -5
- package/skills/cometchat-android-v5-calls/references/event-listeners.md +2 -2
- package/skills/cometchat-android-v5-calls/references/idle-timeout.md +20 -14
- package/skills/cometchat-android-v5-calls/references/in-call-chat.md +1 -1
- package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +43 -27
- package/skills/cometchat-android-v5-calls/references/participant-management.md +3 -3
- package/skills/cometchat-android-v5-calls/references/raise-hand.md +25 -19
- package/skills/cometchat-android-v5-calls/references/recording.md +2 -2
- package/skills/cometchat-android-v5-calls/references/ringing-integration.md +1 -1
- package/skills/cometchat-android-v5-calls/references/screen-sharing.md +5 -9
- package/skills/cometchat-android-v5-calls/references/session-settings.md +3 -3
- package/skills/cometchat-android-v5-calls/references/setup.md +1 -1
- package/skills/cometchat-android-v5-calls/references/share-invite.md +9 -4
- package/skills/cometchat-android-v5-calls/references/video-controls.md +4 -4
- package/skills/cometchat-android-v5-calls/references/voip-calling.md +2 -2
- package/skills/cometchat-android-v5-components/SKILL.md +4 -3
- package/skills/cometchat-android-v5-core/SKILL.md +5 -3
- package/skills/cometchat-android-v5-customization/SKILL.md +171 -7
- package/skills/cometchat-android-v5-extensions/SKILL.md +7 -4
- package/skills/cometchat-android-v5-features/SKILL.md +5 -4
- package/skills/cometchat-android-v5-placement/SKILL.md +2 -1
- package/skills/cometchat-android-v5-production/SKILL.md +2 -1
- package/skills/cometchat-android-v5-push/SKILL.md +2 -3
- package/skills/cometchat-android-v5-testing/SKILL.md +2 -1
- package/skills/cometchat-android-v5-theming/SKILL.md +2 -1
- package/skills/cometchat-android-v5-troubleshooting/SKILL.md +3 -2
- package/skills/cometchat-android-v6/SKILL.md +2 -1
- package/skills/cometchat-android-v6-builder-settings/SKILL.md +11 -7
- package/skills/cometchat-android-v6-calls/SKILL.md +79 -18
- package/skills/cometchat-android-v6-calls/references/advanced-features.md +87 -0
- package/skills/cometchat-android-v6-calls/references/call-layouts.md +24 -15
- package/skills/cometchat-android-v6-calls/references/call-session.md +2 -2
- package/skills/cometchat-android-v6-calls/references/device-management.md +17 -16
- package/skills/cometchat-android-v6-calls/references/idle-timeout.md +7 -4
- package/skills/cometchat-android-v6-calls/references/in-call-chat.md +13 -8
- package/skills/cometchat-android-v6-calls/references/raise-hand.md +6 -4
- package/skills/cometchat-android-v6-compose-components/SKILL.md +52 -29
- package/skills/cometchat-android-v6-compose-customization/SKILL.md +156 -1
- package/skills/cometchat-android-v6-compose-placement/SKILL.md +129 -40
- package/skills/cometchat-android-v6-compose-theming/SKILL.md +27 -1
- package/skills/cometchat-android-v6-core/SKILL.md +208 -28
- package/skills/cometchat-android-v6-events/SKILL.md +4 -1
- package/skills/cometchat-android-v6-extensions/SKILL.md +2 -1
- package/skills/cometchat-android-v6-features/SKILL.md +26 -2
- package/skills/cometchat-android-v6-kotlin-components/SKILL.md +31 -1
- package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +172 -1
- package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +20 -5
- package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +36 -5
- package/skills/cometchat-android-v6-migration/SKILL.md +44 -42
- package/skills/cometchat-android-v6-production/SKILL.md +6 -3
- package/skills/cometchat-android-v6-push/SKILL.md +43 -2
- package/skills/cometchat-android-v6-testing/SKILL.md +11 -8
- package/skills/cometchat-android-v6-troubleshooting/SKILL.md +26 -5
- package/skills/cometchat-angular-calls/SKILL.md +256 -389
- package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +3 -2
- package/skills/cometchat-angular-calls/references/call-layouts.md +29 -12
- package/skills/cometchat-angular-calls/references/call-session.md +2 -2
- package/skills/cometchat-angular-calls/references/custom-ui.md +18 -10
- package/skills/cometchat-angular-calls/references/device-management.md +53 -34
- package/skills/cometchat-angular-calls/references/group-calls.md +45 -24
- package/skills/cometchat-angular-calls/references/idle-timeout.md +31 -15
- package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +7 -6
- package/skills/cometchat-angular-calls/references/raise-hand.md +9 -4
- package/skills/cometchat-angular-calls/references/recording-screen-share.md +32 -39
- package/skills/cometchat-angular-calls/references/ringing-integration.md +3 -1
- package/skills/cometchat-angular-calls/references/share-invite.md +11 -5
- package/skills/cometchat-angular-calls/references/virtual-background.md +29 -0
- package/skills/cometchat-angular-components/SKILL.md +149 -620
- package/skills/cometchat-angular-core/SKILL.md +232 -312
- package/skills/cometchat-angular-customization/SKILL.md +415 -223
- package/skills/cometchat-angular-features/SKILL.md +216 -334
- package/skills/cometchat-angular-patterns/SKILL.md +168 -359
- package/skills/cometchat-angular-placement/SKILL.md +189 -560
- package/skills/cometchat-angular-production/SKILL.md +241 -92
- package/skills/cometchat-angular-push/SKILL.md +280 -294
- package/skills/cometchat-angular-testing/SKILL.md +430 -158
- package/skills/cometchat-angular-theming/SKILL.md +190 -265
- package/skills/cometchat-angular-troubleshooting/SKILL.md +192 -157
- package/skills/cometchat-astro-patterns/SKILL.md +3 -2
- package/skills/cometchat-calls/SKILL.md +25 -19
- package/skills/cometchat-calls/references/use-case-broadcast.md +15 -10
- package/skills/cometchat-calls/references/use-case-marketplace.md +2 -3
- package/skills/cometchat-calls/references/use-case-support.md +3 -4
- package/skills/cometchat-calls/references/use-case-team.md +23 -12
- package/skills/cometchat-calls/references/use-case-telehealth.md +3 -4
- package/skills/cometchat-components/SKILL.md +163 -25
- package/skills/cometchat-core/SKILL.md +258 -20
- package/skills/cometchat-customization/SKILL.md +50 -25
- package/skills/cometchat-features/SKILL.md +314 -35
- package/skills/cometchat-flutter-v5/SKILL.md +10 -4
- package/skills/cometchat-flutter-v5-calls/SKILL.md +188 -158
- package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +48 -24
- package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +20 -15
- package/skills/cometchat-flutter-v5-calls/references/call-session.md +100 -145
- package/skills/cometchat-flutter-v5-calls/references/device-management.md +12 -8
- package/skills/cometchat-flutter-v5-calls/references/group-calls.md +30 -36
- package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +15 -13
- package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +12 -9
- package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +115 -65
- package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +41 -30
- package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +17 -14
- package/skills/cometchat-flutter-v5-calls/references/share-invite.md +8 -2
- package/skills/cometchat-flutter-v5-conversations/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-core/SKILL.md +5 -4
- package/skills/cometchat-flutter-v5-customization/SKILL.md +136 -5
- package/skills/cometchat-flutter-v5-events/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-messages/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-production/SKILL.md +15 -6
- package/skills/cometchat-flutter-v5-push/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-testing/SKILL.md +17 -6
- package/skills/cometchat-flutter-v5-theming/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +7 -6
- package/skills/cometchat-flutter-v5-users-groups/SKILL.md +3 -2
- package/skills/cometchat-flutter-v6/SKILL.md +17 -16
- package/skills/cometchat-flutter-v6-calls/SKILL.md +72 -57
- package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +5 -3
- package/skills/cometchat-flutter-v6-calls/references/advanced-features.md +89 -0
- package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +15 -12
- package/skills/cometchat-flutter-v6-calls/references/call-session.md +2 -2
- package/skills/cometchat-flutter-v6-calls/references/device-management.md +9 -3
- package/skills/cometchat-flutter-v6-calls/references/group-calls.md +10 -10
- package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +15 -7
- package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +6 -3
- package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +23 -16
- package/skills/cometchat-flutter-v6-components/SKILL.md +32 -11
- package/skills/cometchat-flutter-v6-conversations/SKILL.md +39 -11
- package/skills/cometchat-flutter-v6-core/SKILL.md +182 -21
- package/skills/cometchat-flutter-v6-customization/SKILL.md +97 -25
- package/skills/cometchat-flutter-v6-events/SKILL.md +3 -2
- package/skills/cometchat-flutter-v6-features/SKILL.md +15 -6
- package/skills/cometchat-flutter-v6-messages/SKILL.md +111 -60
- package/skills/cometchat-flutter-v6-migration/SKILL.md +18 -25
- package/skills/cometchat-flutter-v6-placement/SKILL.md +79 -50
- package/skills/cometchat-flutter-v6-production/SKILL.md +13 -12
- package/skills/cometchat-flutter-v6-push/SKILL.md +41 -19
- package/skills/cometchat-flutter-v6-testing/SKILL.md +4 -4
- package/skills/cometchat-flutter-v6-theming/SKILL.md +38 -5
- package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +182 -17
- package/skills/cometchat-flutter-v6-users-groups/SKILL.md +12 -4
- package/skills/cometchat-i18n/SKILL.md +140 -79
- package/skills/cometchat-ios/SKILL.md +4 -2
- package/skills/cometchat-ios-calls/SKILL.md +225 -95
- package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +11 -9
- package/skills/cometchat-ios-calls/references/audio-modes-and-controls.md +45 -0
- package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +6 -7
- package/skills/cometchat-ios-calls/references/call-layouts.md +31 -91
- package/skills/cometchat-ios-calls/references/call-session.md +51 -54
- package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +33 -29
- package/skills/cometchat-ios-calls/references/custom-ui.md +38 -38
- package/skills/cometchat-ios-calls/references/group-calls.md +33 -70
- package/skills/cometchat-ios-calls/references/idle-timeout.md +24 -25
- package/skills/cometchat-ios-calls/references/in-call-chat.md +19 -23
- package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +128 -70
- package/skills/cometchat-ios-calls/references/picture-in-picture.md +20 -20
- package/skills/cometchat-ios-calls/references/raise-hand.md +14 -227
- package/skills/cometchat-ios-calls/references/recording-screen-share.md +35 -122
- package/skills/cometchat-ios-calls/references/ringing-integration.md +17 -16
- package/skills/cometchat-ios-calls/references/share-invite.md +8 -12
- package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +4 -4
- package/skills/cometchat-ios-components/SKILL.md +200 -12
- package/skills/cometchat-ios-core/SKILL.md +173 -45
- package/skills/cometchat-ios-customization/SKILL.md +276 -110
- package/skills/cometchat-ios-features/SKILL.md +64 -36
- package/skills/cometchat-ios-placement/SKILL.md +15 -12
- package/skills/cometchat-ios-production/SKILL.md +12 -4
- package/skills/cometchat-ios-push/SKILL.md +53 -19
- package/skills/cometchat-ios-testing/SKILL.md +14 -9
- package/skills/cometchat-ios-theming/SKILL.md +39 -3
- package/skills/cometchat-ios-troubleshooting/SKILL.md +41 -21
- package/skills/cometchat-native-bare-patterns/SKILL.md +36 -19
- package/skills/cometchat-native-calls/SKILL.md +29 -17
- package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +2 -2
- package/skills/cometchat-native-calls/references/call-layouts.md +15 -14
- package/skills/cometchat-native-calls/references/call-session.md +2 -2
- package/skills/cometchat-native-calls/references/custom-ui.md +12 -8
- package/skills/cometchat-native-calls/references/device-management.md +53 -30
- package/skills/cometchat-native-calls/references/group-calls.md +35 -30
- package/skills/cometchat-native-calls/references/idle-timeout.md +6 -6
- package/skills/cometchat-native-calls/references/in-call-chat.md +10 -8
- package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +2 -2
- package/skills/cometchat-native-calls/references/raise-hand.md +15 -13
- package/skills/cometchat-native-calls/references/recording-screen-share.md +49 -170
- package/skills/cometchat-native-calls/references/share-invite.md +7 -5
- package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +4 -2
- package/skills/cometchat-native-components/SKILL.md +84 -52
- package/skills/cometchat-native-core/SKILL.md +102 -33
- package/skills/cometchat-native-customization/SKILL.md +150 -28
- package/skills/cometchat-native-expo-patterns/SKILL.md +60 -29
- package/skills/cometchat-native-features/SKILL.md +24 -17
- package/skills/cometchat-native-placement/SKILL.md +19 -10
- package/skills/cometchat-native-production/SKILL.md +9 -3
- package/skills/cometchat-native-push/SKILL.md +2 -1
- package/skills/cometchat-native-testing/SKILL.md +1 -2
- package/skills/cometchat-native-theming/SKILL.md +54 -29
- package/skills/cometchat-native-troubleshooting/SKILL.md +11 -5
- package/skills/cometchat-nextjs-patterns/SKILL.md +22 -8
- package/skills/cometchat-placement/SKILL.md +42 -3
- package/skills/cometchat-production/SKILL.md +12 -5
- package/skills/cometchat-react-calls/SKILL.md +220 -10
- package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +4 -3
- package/skills/cometchat-react-calls/references/call-layouts.md +5 -6
- package/skills/cometchat-react-calls/references/call-session.md +1 -1
- package/skills/cometchat-react-calls/references/custom-ui.md +61 -15
- package/skills/cometchat-react-calls/references/device-management.md +55 -51
- package/skills/cometchat-react-calls/references/group-calls.md +18 -23
- package/skills/cometchat-react-calls/references/idle-timeout.md +25 -12
- package/skills/cometchat-react-calls/references/in-call-chat.md +7 -7
- package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +9 -11
- package/skills/cometchat-react-calls/references/raise-hand.md +14 -14
- package/skills/cometchat-react-calls/references/recording-screen-share.md +39 -38
- package/skills/cometchat-react-calls/references/ringing-integration.md +2 -2
- package/skills/cometchat-react-calls/references/share-invite.md +4 -5
- package/skills/cometchat-react-calls/references/testing-calls-on-web.md +20 -2
- package/skills/cometchat-react-calls/references/virtual-background.md +32 -0
- package/skills/cometchat-react-patterns/SKILL.md +45 -5
- package/skills/cometchat-react-push/SKILL.md +258 -72
- package/skills/cometchat-react-router-patterns/SKILL.md +12 -6
- package/skills/cometchat-react-testing/SKILL.md +14 -5
- package/skills/cometchat-theming/SKILL.md +181 -18
- package/skills/cometchat-troubleshooting/SKILL.md +40 -20
|
@@ -1,36 +1,220 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cometchat-react-push
|
|
3
|
-
description: Push notifications for CometChat React UI Kit v6 in Vite / Next.js / React Router / Astro projects.
|
|
3
|
+
description: Push notifications for CometChat React UI Kit v6 in Vite / Next.js / React Router / Astro projects. Recommended path is CometChat-native web push via Firebase Cloud Messaging for Web — `CometChatNotifications.registerPushToken(token, PushPlatforms.FCM_WEB)` + a dashboard FCM provider, so CometChat's own backend delivers new-message pushes with NO self-hosted push server. Also documents an optional advanced self-hosted Web Push fallback (Service Worker + Push API + VAPID + message-sent webhook) for projects that can't use Firebase. Covers click-through to chat, foreground vs background handling, iOS Safari 16.4+ PWA-only quirks, and HTTPS requirements.
|
|
4
4
|
license: "MIT"
|
|
5
|
-
compatibility: "React >= 18; Web Push API (Chrome 50+, Firefox 44+, Edge 17+, Safari 16+ desktop, Safari 16.4+ iOS PWA-only); HTTPS required (or localhost)
|
|
6
|
-
allowed-tools: "shell, file-read, file-search, file-list, ask-user"
|
|
5
|
+
compatibility: "React >= 18; @cometchat/chat-sdk-javascript ^4.1.10 (ships CometChatNotifications.registerPushToken + PushPlatforms.FCM_WEB); firebase modular SDK for FCM_WEB; Web Push API (Chrome 50+, Firefox 44+, Edge 17+, Safari 16+ desktop, Safari 16.4+ iOS PWA-only); HTTPS required (or localhost)"
|
|
7
6
|
metadata:
|
|
8
7
|
author: "CometChat"
|
|
9
|
-
version: "4.
|
|
10
|
-
tags: "cometchat react web push notifications service-worker vapid push-api notification-api ios-safari-pwa nextjs astro react-router"
|
|
8
|
+
version: "4.1.0"
|
|
9
|
+
tags: "cometchat react web push notifications fcm-web firebase cometchatnotifications registerpushtoken service-worker vapid push-api notification-api ios-safari-pwa nextjs astro react-router"
|
|
11
10
|
---
|
|
12
11
|
|
|
13
12
|
## Purpose
|
|
14
13
|
|
|
15
|
-
Web
|
|
14
|
+
Web push for CometChat chat — new-message notifications when the user's tab is backgrounded or closed.
|
|
16
15
|
|
|
17
|
-
**
|
|
16
|
+
**The web DOES have CometChat-native push.** The JS Chat SDK ships a first-class web-push registration API: `CometChatNotifications.registerPushToken(token, PushPlatforms.FCM_WEB)`. Paired with a Firebase Cloud Messaging (FCM) provider configured in the CometChat dashboard, **CometChat's own backend delivers the push on every new message** — no self-hosted push server, no `web-push` lib, no VAPID server of your own, and no message-sent webhook for the basic case. This is the recommended path (§1).
|
|
17
|
+
|
|
18
|
+
A self-hosted Web Push path (your own VAPID keys + push server + CometChat webhook) is documented as an advanced fallback (§7) for projects that can't or won't use Firebase. Don't reach for it unless you have to.
|
|
19
|
+
|
|
20
|
+
**Not the same as the calls Web Push.** Calls Web Push tries to ring the device through a closed tab (best-effort, browser-dependent). Chat push notifies on new messages — different payload + UX. Many apps need both.
|
|
18
21
|
|
|
19
22
|
**Read these other skills first:**
|
|
20
23
|
- `cometchat-core` — provider pattern, login order
|
|
21
24
|
- `cometchat-{react,nextjs,react-router,astro}-patterns` — framework-specific Service Worker registration
|
|
22
25
|
- `cometchat-react-calls/references/voip-and-web-push.md` — calls-specific Web Push (overlap with this; both can coexist)
|
|
23
|
-
- `cometchat-production` — server-minted auth tokens
|
|
26
|
+
- `cometchat-production` — server-minted auth tokens
|
|
27
|
+
|
|
28
|
+
**Ground truth (verified against the JS Chat SDK source):** **Official docs:** https://www.cometchat.com/docs/notifications/overview · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP).
|
|
29
|
+
- `CometChatNotifications.registerPushToken(pushToken: string, platform: PushPlatforms, providerId?: string): Promise<string>` — `chat-sdk-javascript/src/Notifications/CometChatNotifications.ts:616`
|
|
30
|
+
- `CometChatNotifications.unregisterPushToken(): Promise<string>` — `chat-sdk-javascript/src/Notifications/CometChatNotifications.ts:649`
|
|
31
|
+
- `enum PushPlatforms { FCM_WEB = 'fcm_web' }` — `chat-sdk-javascript/src/Notifications/constants/CometChatNotificationsConstants.ts:46-47`
|
|
32
|
+
- The web kit pins `@cometchat/chat-sdk-javascript ^4.1.10`, which has this API.
|
|
33
|
+
- There is NO `PNPlatform` and NO `PushNotificationOptions` symbol — the real names are `PushPlatforms` and `CometChatNotifications`.
|
|
34
|
+
- Firebase Cloud Messaging for Web — https://firebase.google.com/docs/cloud-messaging/js/client
|
|
35
|
+
- Web Push spec / VAPID / Push API (fallback path only) — RFC 8030, RFC 8292, https://developer.mozilla.org/en-US/docs/Web/API/Push_API
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 1. Recommended: CometChat-native web push (FCM_WEB)
|
|
40
|
+
|
|
41
|
+
CometChat delivers web push through **Firebase Cloud Messaging for Web**. You register the FCM device token with CometChat via the Chat SDK; CometChat's backend then sends pushes on new messages through your dashboard-configured FCM provider. No push server of yours.
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
Browser (your React app)
|
|
45
|
+
├── firebase/messaging — getToken() → FCM web token
|
|
46
|
+
├── firebase-messaging-sw.js — receives background pushes (onBackgroundMessage)
|
|
47
|
+
└── CometChatNotifications.registerPushToken(token, FCM_WEB) — hands token to CometChat
|
|
48
|
+
|
|
49
|
+
CometChat backend
|
|
50
|
+
└── FCM provider (dashboard) → sends push to the token on every new message
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 1.1 Firebase setup (one-time)
|
|
54
|
+
|
|
55
|
+
1. Create a Firebase project, enable **Cloud Messaging**.
|
|
56
|
+
2. Add a Web app; copy its web SDK config (`apiKey`, `projectId`, `messagingSenderId`, `appId`, …).
|
|
57
|
+
3. Under **Project Settings → Cloud Messaging → Web configuration**, generate a **Web Push certificate**. This key pair is Firebase's own VAPID key — it is consumed by `getToken({ vapidKey })`. It is NOT a self-hosted VAPID server; you don't run any server for it.
|
|
58
|
+
|
|
59
|
+
### 1.2 Install + initialize Firebase
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install firebase
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
// cometchat/firebase.ts
|
|
67
|
+
import { initializeApp } from "firebase/app";
|
|
68
|
+
|
|
69
|
+
export const firebaseApp = initializeApp({
|
|
70
|
+
apiKey: import.meta.env.VITE_FIREBASE_API_KEY, // adjust prefix per framework
|
|
71
|
+
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
|
|
72
|
+
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
|
|
73
|
+
messagingSenderId: import.meta.env.VITE_FIREBASE_SENDER_ID,
|
|
74
|
+
appId: import.meta.env.VITE_FIREBASE_APP_ID,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
export const FIREBASE_WEB_PUSH_CERT_KEY = import.meta.env.VITE_FIREBASE_VAPID_KEY; // Web Push certificate key
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 1.3 Service worker — `public/firebase-messaging-sw.js`
|
|
81
|
+
|
|
82
|
+
The file MUST live at the origin root (`/firebase-messaging-sw.js`) — `getToken` looks for it by default, or pass an explicit `serviceWorkerRegistration`.
|
|
83
|
+
|
|
84
|
+
> **Coexistence check first (P0-10).** If `detect` reported `coexistence.existing_firebase: true` or listed an existing service worker, the project already runs Firebase and/or a SW. Do NOT blindly overwrite: (a) reuse the project's existing Firebase config/app instead of a second `initializeApp` — duplicate apps fight over the FCM token; (b) if a service worker already exists at the origin root (e.g. a PWA/Workbox `sw.js`), **merge** the messaging handlers (`importScripts` + `firebase.initializeApp` + `onBackgroundMessage`) into it rather than replacing it, or register CometChat's worker at a distinct scope and pass it as `serviceWorkerRegistration` to `getToken`. Overwriting the app's worker silently kills its offline/caching logic.
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
// public/firebase-messaging-sw.js
|
|
88
|
+
importScripts("https://www.gstatic.com/firebasejs/10.12.0/firebase-app-compat.js");
|
|
89
|
+
importScripts("https://www.gstatic.com/firebasejs/10.12.0/firebase-messaging-compat.js");
|
|
90
|
+
|
|
91
|
+
firebase.initializeApp({
|
|
92
|
+
apiKey: "…",
|
|
93
|
+
projectId: "…",
|
|
94
|
+
messagingSenderId: "…",
|
|
95
|
+
appId: "…",
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const messaging = firebase.messaging();
|
|
99
|
+
|
|
100
|
+
// Background pushes (tab closed / not focused)
|
|
101
|
+
messaging.onBackgroundMessage((payload) => {
|
|
102
|
+
const { title, body } = payload.notification ?? {};
|
|
103
|
+
self.registration.showNotification(title ?? "New message", {
|
|
104
|
+
body: body ?? "",
|
|
105
|
+
icon: "/icons/chat.png",
|
|
106
|
+
tag: payload.data?.conversationId ? `chat-${payload.data.conversationId}` : undefined,
|
|
107
|
+
data: payload.data ?? {},
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
self.addEventListener("notificationclick", (event) => {
|
|
112
|
+
event.notification.close();
|
|
113
|
+
const data = event.notification.data ?? {};
|
|
114
|
+
const targetUrl = data.receiverType === "group"
|
|
115
|
+
? `/messages?group=${data.conversationId}`
|
|
116
|
+
: `/messages?user=${data.senderUid ?? data.conversationId}`;
|
|
117
|
+
event.waitUntil(
|
|
118
|
+
clients.matchAll({ type: "window", includeUncontrolled: true }).then((wins) => {
|
|
119
|
+
for (const w of wins) {
|
|
120
|
+
if (w.url.includes(self.registration.scope)) {
|
|
121
|
+
w.focus();
|
|
122
|
+
w.postMessage({ type: "open_conversation", ...data });
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return clients.openWindow(targetUrl);
|
|
127
|
+
}),
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 1.4 Register the FCM token with CometChat (after login)
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
// cometchat/registerFcmWebPush.ts
|
|
136
|
+
import { getMessaging, getToken, onMessage } from "firebase/messaging";
|
|
137
|
+
import { CometChatNotifications } from "@cometchat/chat-sdk-javascript";
|
|
138
|
+
import { firebaseApp, FIREBASE_WEB_PUSH_CERT_KEY } from "./firebase";
|
|
139
|
+
|
|
140
|
+
export async function registerFcmWebPush(): Promise<void> {
|
|
141
|
+
if (!("serviceWorker" in navigator) || !("Notification" in window)) return;
|
|
142
|
+
|
|
143
|
+
// Permission MUST be requested in response to a user gesture (see §2 rule).
|
|
144
|
+
const permission = await Notification.requestPermission();
|
|
145
|
+
if (permission !== "granted") return;
|
|
146
|
+
|
|
147
|
+
// Register the FCM service worker.
|
|
148
|
+
const swReg = await navigator.serviceWorker.register("/firebase-messaging-sw.js");
|
|
149
|
+
|
|
150
|
+
const messaging = getMessaging(firebaseApp);
|
|
151
|
+
const fcmToken = await getToken(messaging, {
|
|
152
|
+
vapidKey: FIREBASE_WEB_PUSH_CERT_KEY, // Firebase Web Push certificate — NOT a self-hosted VAPID server
|
|
153
|
+
serviceWorkerRegistration: swReg,
|
|
154
|
+
});
|
|
155
|
+
if (!fcmToken) return;
|
|
156
|
+
|
|
157
|
+
// Hand the token to CometChat. Its backend now delivers pushes on new messages.
|
|
158
|
+
await CometChatNotifications.registerPushToken(
|
|
159
|
+
fcmToken,
|
|
160
|
+
CometChatNotifications.PushPlatforms.FCM_WEB,
|
|
161
|
+
/* providerId */ undefined, // omit for "default", or pass your dashboard FCM provider id
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
// Foreground messages (tab focused) don't fire the SW — show them yourself if desired.
|
|
165
|
+
onMessage(messaging, (payload) => {
|
|
166
|
+
if (document.visibilityState === "visible") {
|
|
167
|
+
// e.g. toast / in-app banner instead of an OS notification
|
|
168
|
+
window.dispatchEvent(new CustomEvent("cometchat:foreground-push", { detail: payload }));
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Call it from your provider AFTER `CometChatUIKit.login(...)` resolves:
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
// CometChatProvider.tsx
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
if (!user) return;
|
|
180
|
+
registerFcmWebPush().catch((err) => {
|
|
181
|
+
console.warn("FCM web push registration failed:", err); // never block chat — push is opt-in
|
|
182
|
+
});
|
|
183
|
+
}, [user]);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 1.5 Dashboard FCM provider (manual, one-time)
|
|
187
|
+
|
|
188
|
+
In the CometChat dashboard: **Notifications → Push Notifications → Add FCM provider**. Upload the Firebase service-account JSON (or legacy server key) for the same Firebase project. CometChat now sends new-message pushes to every registered `FCM_WEB` token — **no webhook of yours**.
|
|
189
|
+
|
|
190
|
+
### 1.6 Logout — unregister the token
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import { CometChatNotifications } from "@cometchat/chat-sdk-javascript";
|
|
194
|
+
|
|
195
|
+
// Call BEFORE CometChat.logout(), while the auth token is still valid.
|
|
196
|
+
await CometChatNotifications.unregisterPushToken(); // CometChatNotifications.ts:649
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
> **Hard rule — register only AFTER login.** `registerPushToken` operates on the current logged-in user's auth token. Calling it before `CometChatUIKit.login(...)` resolves will fail or attach the token to nobody. Wire it inside the auth-state effect, never on page load.
|
|
24
200
|
|
|
25
|
-
**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
201
|
+
> **Hard rule — `firebase-messaging-sw.js` must be at the origin root.** Place it in `public/` so it serves from `/firebase-messaging-sw.js`. In Next.js it cannot live under `app/`. See §8 for per-framework placement.
|
|
202
|
+
|
|
203
|
+
> **Hard rule — iOS still needs PWA install.** FCM web push on iOS 16.4+ only works for a Home-Screen-installed PWA, exactly like the fallback path. See §9.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 2. The permission-prompt rule (applies to both paths)
|
|
208
|
+
|
|
209
|
+
Chrome / Firefox / Safari all require `Notification.requestPermission()` to run in response to a **user gesture** (a click). Calling it from a top-level `useEffect` on page load is rejected. Best pattern: an "Enable notifications" button the user clicks once, which then calls `registerFcmWebPush()` (or the fallback `registerWebPushForChat()`).
|
|
30
210
|
|
|
31
211
|
---
|
|
32
212
|
|
|
33
|
-
##
|
|
213
|
+
## 3. Alternative / advanced: self-hosted Web Push (no Firebase)
|
|
214
|
+
|
|
215
|
+
> Use this path **only** if you cannot or will not use Firebase (§1). It is more work — you run your own VAPID keys, a push server, and a CometChat message-sent webhook. CometChat's backend does NOT deliver the push for you on this path; your server does. For most apps, prefer §1.
|
|
216
|
+
|
|
217
|
+
### 3.1 Architecture
|
|
34
218
|
|
|
35
219
|
```
|
|
36
220
|
Browser (your React app)
|
|
@@ -47,11 +231,9 @@ Your push server (Node, Cloudflare Worker, Lambda, etc.)
|
|
|
47
231
|
└── Sends push payload via web-push lib → browser
|
|
48
232
|
```
|
|
49
233
|
|
|
50
|
-
Three pieces, all yours: client SW, push server, webhook integration.
|
|
234
|
+
Three pieces, all yours: client SW, push server, webhook integration.
|
|
51
235
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
## 2. Generate VAPID keys (server-side, one-time)
|
|
236
|
+
### 3.2 Generate VAPID keys (server-side, one-time)
|
|
55
237
|
|
|
56
238
|
VAPID = Voluntary Application Server Identification — proves to the browser that the push originated from an authorized server.
|
|
57
239
|
|
|
@@ -69,11 +251,9 @@ Private Key: 9tT...
|
|
|
69
251
|
|
|
70
252
|
Public key → client (env var). Private key → push server only (never ship to client).
|
|
71
253
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
## 3. Service Worker
|
|
254
|
+
### 3.3 Service Worker
|
|
75
255
|
|
|
76
|
-
|
|
256
|
+
#### `public/sw.js` (Vite / CRA / React Router) or `app/sw.js` (Next.js / Astro)
|
|
77
257
|
|
|
78
258
|
```js
|
|
79
259
|
// Fired when a push payload arrives
|
|
@@ -135,9 +315,7 @@ self.addEventListener("notificationclose", (event) => {
|
|
|
135
315
|
});
|
|
136
316
|
```
|
|
137
317
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
## 4. Client-side registration
|
|
318
|
+
### 3.4 Client-side registration (self-hosted)
|
|
141
319
|
|
|
142
320
|
```ts
|
|
143
321
|
// cometchat/registerWebPush.ts
|
|
@@ -193,11 +371,9 @@ useEffect(() => {
|
|
|
193
371
|
}, [user]);
|
|
194
372
|
```
|
|
195
373
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
---
|
|
374
|
+
The permission-prompt rule (§2) applies here too — request permission from a user gesture, not page load.
|
|
199
375
|
|
|
200
|
-
|
|
376
|
+
### 3.5 Listen for SW messages in the React app
|
|
201
377
|
|
|
202
378
|
```tsx
|
|
203
379
|
// CometChatProvider.tsx
|
|
@@ -216,9 +392,7 @@ useEffect(() => {
|
|
|
216
392
|
|
|
217
393
|
When the SW posts `open_conversation`, the React app navigates to the right thread.
|
|
218
394
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
## 6. Server-side push send
|
|
395
|
+
### 3.6 Server-side push send
|
|
222
396
|
|
|
223
397
|
Your push server runs on Node.js / Cloudflare Worker / Lambda / Vercel Functions. The shape:
|
|
224
398
|
|
|
@@ -287,9 +461,7 @@ app.listen(3000);
|
|
|
287
461
|
|
|
288
462
|
The skill writes a starter version of this server file (`server/push.example.ts`) with a README pointing at env vars; the user owns the actual deployment.
|
|
289
463
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
## 7. CometChat webhook setup (manual)
|
|
464
|
+
### 3.7 CometChat webhook setup (manual)
|
|
293
465
|
|
|
294
466
|
In the CometChat dashboard:
|
|
295
467
|
|
|
@@ -301,9 +473,7 @@ In the CometChat dashboard:
|
|
|
301
473
|
|
|
302
474
|
The webhook fires for EVERY message — your server filters out the sender, dedupes per conversation, and respects user notification preferences.
|
|
303
475
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
## 8. Webhook signature verification
|
|
476
|
+
### 3.8 Webhook signature verification
|
|
307
477
|
|
|
308
478
|
```ts
|
|
309
479
|
import crypto from "crypto";
|
|
@@ -323,7 +493,7 @@ Without this, anyone with your endpoint URL can flood your users with fake notif
|
|
|
323
493
|
|
|
324
494
|
---
|
|
325
495
|
|
|
326
|
-
##
|
|
496
|
+
## 4. Browser support matrix + iOS PWA caveat (both paths)
|
|
327
497
|
|
|
328
498
|
| Browser | Web Push | Notification while closed | Notes |
|
|
329
499
|
|---|---|---|---|
|
|
@@ -335,7 +505,7 @@ Without this, anyone with your endpoint URL can flood your users with fake notif
|
|
|
335
505
|
| Chrome mobile | ✓ | ✓ | Aggressive throttling on Android |
|
|
336
506
|
| Edge mobile | ✓ | ✓ | Same as Chrome mobile |
|
|
337
507
|
|
|
338
|
-
**iOS PWA-only requirement:** iOS 16.4+ supports
|
|
508
|
+
**iOS PWA-only requirement (applies to FCM_WEB too):** iOS 16.4+ supports web push, but ONLY for sites added to the Home Screen as a PWA. Safari-the-browser-app does NOT receive push. This is platform-level and applies equally to the FCM_WEB path (§1) and the self-hosted path (§3). To unlock iOS web push:
|
|
339
509
|
|
|
340
510
|
1. App must have a `manifest.json` (PWA manifest)
|
|
341
511
|
2. User must use Safari → Share → "Add to Home Screen"
|
|
@@ -345,39 +515,41 @@ This is a real production constraint. The skill detects whether the project ship
|
|
|
345
515
|
|
|
346
516
|
---
|
|
347
517
|
|
|
348
|
-
##
|
|
518
|
+
## 5. Framework-specific service worker placement (both paths)
|
|
519
|
+
|
|
520
|
+
The FCM service worker (`firebase-messaging-sw.js`, §1) and the self-hosted SW (`sw.js`, §3) follow the same placement rules.
|
|
349
521
|
|
|
350
522
|
### Vite / React (CRA)
|
|
351
523
|
|
|
352
|
-
`public/sw.js` is served from
|
|
524
|
+
`public/firebase-messaging-sw.js` (or `public/sw.js`) is served from the origin root. `register("/firebase-messaging-sw.js")` works directly.
|
|
353
525
|
|
|
354
526
|
### Next.js (App Router)
|
|
355
527
|
|
|
356
|
-
Service Workers + Next.js have a known gotcha: the SW can't be inside `app/` because Next handles those routes. Place it in `public
|
|
528
|
+
Service Workers + Next.js have a known gotcha: the SW can't be inside `app/` because Next handles those routes. Place it in `public/` and serve from the origin root. Register from a `"use client"` component that runs after hydration.
|
|
357
529
|
|
|
358
530
|
### Next.js (Pages Router)
|
|
359
531
|
|
|
360
|
-
Same — `public
|
|
532
|
+
Same — `public/`.
|
|
361
533
|
|
|
362
534
|
### React Router
|
|
363
535
|
|
|
364
|
-
`public
|
|
536
|
+
`public/` works. If using SSR (loaders), the SW registration code must be guarded by `typeof window !== "undefined"`.
|
|
365
537
|
|
|
366
538
|
### Astro
|
|
367
539
|
|
|
368
|
-
Place the SW at `public
|
|
540
|
+
Place the SW at `public/`. Register from a `client:only="react"` island.
|
|
369
541
|
|
|
370
542
|
The framework-specific patterns skills cover the SSR guards in detail.
|
|
371
543
|
|
|
372
544
|
---
|
|
373
545
|
|
|
374
|
-
##
|
|
546
|
+
## 6. HTTPS requirement (both paths)
|
|
375
547
|
|
|
376
|
-
Service Workers + Push API
|
|
548
|
+
Service Workers + Push API + FCM all require HTTPS (or `localhost` for dev). The skill detects the dev server protocol and warns:
|
|
377
549
|
|
|
378
550
|
```
|
|
379
|
-
⚠️ Web
|
|
380
|
-
|
|
551
|
+
⚠️ Web push requires HTTPS or localhost. Your dev server is running on http://192.168.x.x.
|
|
552
|
+
Push subscriptions will fail. Either:
|
|
381
553
|
- Use http://localhost (Chrome/Firefox/Safari all allow Push API on localhost), or
|
|
382
554
|
- Set up HTTPS dev (mkcert, ngrok, or Vite's --https flag)
|
|
383
555
|
```
|
|
@@ -386,19 +558,23 @@ For production, the Vercel / Netlify / Cloudflare default deploys are HTTPS —
|
|
|
386
558
|
|
|
387
559
|
---
|
|
388
560
|
|
|
389
|
-
##
|
|
561
|
+
## 7. Anti-patterns
|
|
390
562
|
|
|
391
|
-
1. **
|
|
392
|
-
2. **
|
|
393
|
-
3. **
|
|
394
|
-
4. **
|
|
395
|
-
5. **
|
|
396
|
-
6. **
|
|
397
|
-
7. **
|
|
563
|
+
1. **Believing "the web has no CometChat push."** It does — `CometChatNotifications.registerPushToken(token, PushPlatforms.FCM_WEB)` + a dashboard FCM provider (§1). Don't hand-roll a push server unless you've ruled out Firebase.
|
|
564
|
+
2. **Inventing SDK symbols.** There is no `PNPlatform`, no `PushNotificationOptions`. The real names are `CometChatNotifications` and `PushPlatforms` (only member: `FCM_WEB`).
|
|
565
|
+
3. **Calling `registerPushToken` before login.** It binds to the current logged-in user's auth token — call it only after `CometChatUIKit.login(...)` resolves.
|
|
566
|
+
4. **Calling `Notification.requestPermission()` on page load.** Browsers reject this. Wire to a user-clicked "Enable notifications" button (§2).
|
|
567
|
+
5. **Self-hosted path: sending the Auth Key in push payloads.** Payloads are visible in the SW; never include credentials. Use the user's UID as a key into your server's session store.
|
|
568
|
+
6. **Self-hosted path: missing webhook signature verification.** Without HMAC verification, anyone with the URL can spoof notifications.
|
|
569
|
+
7. **Showing notifications even when the chat tab is open.** Check `clients.matchAll()` (self-hosted) or `document.visibilityState` in `onMessage` (FCM) and skip if the user already has the chat focused.
|
|
570
|
+
8. **Skipping the iOS PWA warning.** iOS users will silently get nothing. Tell them to "Add to Home Screen."
|
|
571
|
+
9. **Forgetting cleanup on logout.** FCM path: call `CometChatNotifications.unregisterPushToken()` (§1.6). Self-hosted path: `subscription.unsubscribe()` + DELETE the server record (§8). Otherwise the previous user keeps getting the new user's messages.
|
|
398
572
|
|
|
399
573
|
---
|
|
400
574
|
|
|
401
|
-
##
|
|
575
|
+
## 8. Self-hosted logout cleanup
|
|
576
|
+
|
|
577
|
+
(FCM_WEB logout uses `CometChatNotifications.unregisterPushToken()` — see §1.6. This is the self-hosted equivalent.)
|
|
402
578
|
|
|
403
579
|
```ts
|
|
404
580
|
async function unsubscribeWebPush(uid: string): Promise<void> {
|
|
@@ -420,29 +596,39 @@ Call this from your logout flow before `CometChat.logout()`.
|
|
|
420
596
|
|
|
421
597
|
---
|
|
422
598
|
|
|
423
|
-
##
|
|
599
|
+
## 9. Verification checklist
|
|
600
|
+
|
|
601
|
+
**Recommended FCM_WEB path (§1):**
|
|
602
|
+
- [ ] `firebase` installed; `firebaseApp` initialized with the web SDK config
|
|
603
|
+
- [ ] Firebase Web Push certificate generated and wired as `getToken({ vapidKey })`
|
|
604
|
+
- [ ] `public/firebase-messaging-sw.js` at origin root, handles `onBackgroundMessage` + `notificationclick`
|
|
605
|
+
- [ ] `Notification.requestPermission()` triggered from a user gesture, not page load (§2)
|
|
606
|
+
- [ ] `CometChatNotifications.registerPushToken(token, CometChatNotifications.PushPlatforms.FCM_WEB)` called AFTER `CometChatUIKit.login(...)` resolves
|
|
607
|
+
- [ ] FCM provider configured in the CometChat dashboard (Notifications → Push)
|
|
608
|
+
- [ ] Foreground `onMessage` does NOT pop an OS notification when the tab is focused
|
|
609
|
+
- [ ] Logout flow calls `CometChatNotifications.unregisterPushToken()` before `CometChat.logout()`
|
|
610
|
+
- [ ] No phantom symbols (`PNPlatform` / `PushNotificationOptions`) anywhere
|
|
424
611
|
|
|
425
|
-
|
|
426
|
-
- [ ]
|
|
427
|
-
- [ ]
|
|
428
|
-
- [ ]
|
|
429
|
-
|
|
612
|
+
**Common to both paths:**
|
|
613
|
+
- [ ] HTTPS or localhost only (warned otherwise)
|
|
614
|
+
- [ ] `manifest.json` shipped if iOS users are expected (PWA caveat, §4)
|
|
615
|
+
- [ ] Notifications dedupe per conversation via `tag` field
|
|
616
|
+
|
|
617
|
+
**Self-hosted fallback path (§3) only:**
|
|
618
|
+
- [ ] `public/sw.js` exists and listens for `push` + `notificationclick` events
|
|
619
|
+
- [ ] VAPID public key in client env vars; private key in server env, NOT client
|
|
430
620
|
- [ ] Subscription POSTed to your push server, keyed by CometChat UID
|
|
431
621
|
- [ ] CometChat dashboard webhook configured for `Message sent` events
|
|
432
622
|
- [ ] Webhook signature verification on the push server (HMAC SHA256)
|
|
433
|
-
- [ ] Notifications dedupe per conversation via `tag` field
|
|
434
|
-
- [ ] `notificationclick` focuses existing tab via `clients.matchAll` OR opens new tab
|
|
435
|
-
- [ ] Foreground tab does NOT show notifications (check tab focus before `showNotification`)
|
|
436
623
|
- [ ] Logout flow calls `subscription.unsubscribe()` and deletes server record
|
|
437
|
-
- [ ] HTTPS or localhost only (warned otherwise)
|
|
438
|
-
- [ ] `manifest.json` shipped if iOS users are expected (PWA caveat)
|
|
439
624
|
- [ ] Server cleanup of dead subscriptions on 410 response
|
|
440
625
|
|
|
441
626
|
---
|
|
442
627
|
|
|
443
|
-
##
|
|
628
|
+
## 10. Pointers
|
|
444
629
|
|
|
445
630
|
- `cometchat-react-calls/references/voip-and-web-push.md` — Web Push for incoming calls (overlap; both can coexist on the same SW)
|
|
446
631
|
- `cometchat-{react,nextjs,react-router,astro}-patterns` — framework-specific SSR handling
|
|
447
632
|
- `cometchat-production` — auth tokens, security
|
|
448
|
-
- `cometchat-troubleshooting` —
|
|
633
|
+
- `cometchat-troubleshooting` — web push debugging (chrome://serviceworker-internals, Firefox about:debugging)
|
|
634
|
+
- Firebase Cloud Messaging for Web — https://firebase.google.com/docs/cloud-messaging/js/client
|
|
@@ -3,13 +3,14 @@ name: cometchat-react-router-patterns
|
|
|
3
3
|
description: "Framework-specific patterns for integrating CometChat React UI Kit v6 into React Router projects (v6 library mode and v7 framework mode). Covers SSR prevention, routing patterns, outlet nesting, and common pitfalls."
|
|
4
4
|
license: "MIT"
|
|
5
5
|
compatibility: "Node.js >=18; React >=18; react-router-dom ^6 or react-router ^7; @cometchat/chat-uikit-react ^6; @cometchat/chat-sdk-javascript ^4"
|
|
6
|
-
allowed-tools: "shell, file-read, file-search, file-list"
|
|
7
6
|
metadata:
|
|
8
7
|
author: "CometChat"
|
|
9
8
|
version: "3.0.0"
|
|
10
9
|
tags: "chat cometchat react-router remix routing ssr patterns"
|
|
11
10
|
---
|
|
12
11
|
|
|
12
|
+
> **Ground truth:** `@cometchat/chat-uikit-react@^6` (+ `@cometchat/calls-sdk-javascript@^5`) — installed package types + `ui-kit/react`. **Official docs:** https://www.cometchat.com/docs/ui-kit/react/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.
|
|
13
|
+
|
|
13
14
|
## Purpose
|
|
14
15
|
|
|
15
16
|
This skill teaches Claude how to integrate CometChat into React Router projects. React Router exists in two distinct modes with very different integration patterns:
|
|
@@ -193,15 +194,20 @@ export default function ConversationView() {
|
|
|
193
194
|
useEffect(() => {
|
|
194
195
|
if (!conversationId) return;
|
|
195
196
|
|
|
196
|
-
//
|
|
197
|
+
// NOTE: this `:conversationId` param is OUR custom URL scheme — the prefix is
|
|
198
|
+
// chosen by the navigate() in ConversationsList below ("user_<uid>" / "group_<guid>").
|
|
199
|
+
// Do NOT confuse it with CometChat's raw Conversation.getConversationId(), which
|
|
200
|
+
// for a 1:1 is "<loggedInUid>_user_<peerUid>" (the "_user_" sits in the MIDDLE,
|
|
201
|
+
// so startsWith("user_") would never match it). Both ends must agree on the
|
|
202
|
+
// custom scheme; branch only on that prefix here.
|
|
197
203
|
if (conversationId.startsWith("user_")) {
|
|
198
|
-
const uid = conversationId.
|
|
204
|
+
const uid = conversationId.slice("user_".length);
|
|
199
205
|
CometChat.getUser(uid).then((u) => {
|
|
200
206
|
setUser(u);
|
|
201
207
|
setGroup(undefined);
|
|
202
208
|
});
|
|
203
209
|
} else if (conversationId.startsWith("group_")) {
|
|
204
|
-
const guid = conversationId.
|
|
210
|
+
const guid = conversationId.slice("group_".length);
|
|
205
211
|
CometChat.getGroup(guid).then((g) => {
|
|
206
212
|
setUser(undefined);
|
|
207
213
|
setGroup(g);
|
|
@@ -697,7 +703,7 @@ Do not mix v6 and v7 patterns. Detect the mode (section 1) and use the correct p
|
|
|
697
703
|
|
|
698
704
|
## 8. Complete integration checklist (v6 library mode)
|
|
699
705
|
|
|
700
|
-
1. Install packages: `npm install @cometchat/chat-uikit-react @cometchat/chat-sdk-javascript`
|
|
706
|
+
1. Install packages: `npm install @cometchat/chat-uikit-react@^6 @cometchat/chat-sdk-javascript@^4` — **⚠️ keep the `@^6` major pin; never install bare.** v7 is on npm — a bare `npm install @cometchat/chat-uikit-react` pulls it once it's tagged `latest`, and these v6 skills break against the v7 API.
|
|
701
707
|
2. Create `.env` with `VITE_COMETCHAT_APP_ID`, `VITE_COMETCHAT_REGION`, `VITE_COMETCHAT_AUTH_KEY`
|
|
702
708
|
3. Add `.env` to `.gitignore`
|
|
703
709
|
4. Import `@cometchat/chat-uikit-react/css-variables.css` in `src/main.tsx`
|
|
@@ -709,7 +715,7 @@ Do not mix v6 and v7 patterns. Detect the mode (section 1) and use the correct p
|
|
|
709
715
|
|
|
710
716
|
## 9. Complete integration checklist (v7 framework mode)
|
|
711
717
|
|
|
712
|
-
1. Install packages: `npm install @cometchat/chat-uikit-react @cometchat/chat-sdk-javascript`
|
|
718
|
+
1. Install packages: `npm install @cometchat/chat-uikit-react@^6 @cometchat/chat-sdk-javascript@^4` — **⚠️ keep the `@^6` major pin; never install bare.** v7 is on npm — a bare `npm install @cometchat/chat-uikit-react` pulls it once it's tagged `latest`, and these v6 skills break against the v7 API.
|
|
713
719
|
2. Create `.env` with `VITE_COMETCHAT_APP_ID`, `VITE_COMETCHAT_REGION`, `VITE_COMETCHAT_AUTH_KEY`
|
|
714
720
|
3. Add `.env` to `.gitignore`
|
|
715
721
|
4. Import `@cometchat/chat-uikit-react/css-variables.css` in `app/root.tsx`
|
|
@@ -3,7 +3,6 @@ name: cometchat-react-testing
|
|
|
3
3
|
description: Testing patterns for CometChat React UI Kit v6 in Vite / Next.js / React Router / Astro projects. Covers Vitest + React Testing Library setup, mocking @cometchat/chat-sdk-javascript and @cometchat/chat-uikit-react, Playwright e2e for full chat flows, the chat-specific assertions (init resolves before render, error UI visible, no Auth Key in test files, css-variables.css imported once), and CI configuration. Sister skill of cometchat-react-calls/references/testing-calls-on-web.md.
|
|
4
4
|
license: "MIT"
|
|
5
5
|
compatibility: "React >= 18, Vitest >= 1, Vite >= 5, @testing-library/react >= 14, Playwright >= 1.40; @cometchat/chat-uikit-react ^6.x"
|
|
6
|
-
allowed-tools: "shell, file-read, file-search, file-list, ask-user"
|
|
7
6
|
metadata:
|
|
8
7
|
author: "CometChat"
|
|
9
8
|
version: "4.0.0"
|
|
@@ -19,7 +18,7 @@ Test recipes for CometChat React UI Kit integrations. Three layers — unit, com
|
|
|
19
18
|
- `cometchat-{react,nextjs,react-router,astro}-patterns` — framework-specific render gates
|
|
20
19
|
- `cometchat-react-calls/references/testing-calls-on-web.md` — the calls-specific testing patterns (this skill is for chat)
|
|
21
20
|
|
|
22
|
-
**Ground truth:**
|
|
21
|
+
**Ground truth:** **Official docs:** https://www.cometchat.com/docs/ui-kit/react/overview · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP).
|
|
23
22
|
- Vitest docs — https://vitest.dev/
|
|
24
23
|
- React Testing Library — https://testing-library.com/docs/react-testing-library/intro
|
|
25
24
|
- Playwright — https://playwright.dev/
|
|
@@ -112,7 +111,9 @@ vi.mock("@cometchat/chat-sdk-javascript", () => ({
|
|
|
112
111
|
setRegion() { return this; }
|
|
113
112
|
build() { return {}; }
|
|
114
113
|
},
|
|
115
|
-
|
|
114
|
+
// Regions are flat string statics (REGION_US/REGION_EU/REGION_IN) — there is
|
|
115
|
+
// no CometChat.REGION object. Pass the region as a plain string ("us"/"eu"/"in").
|
|
116
|
+
REGION_US: "us", REGION_EU: "eu", REGION_IN: "in",
|
|
116
117
|
},
|
|
117
118
|
}));
|
|
118
119
|
|
|
@@ -136,7 +137,8 @@ vi.mock("@cometchat/chat-uikit-react", () => ({
|
|
|
136
137
|
CometChatUsers: () => null,
|
|
137
138
|
CometChatGroups: () => null,
|
|
138
139
|
CometChatIncomingCall: () => null,
|
|
139
|
-
|
|
140
|
+
// NOTE: the v6 web kit has NO CometChatThemeProvider (theming is CSS-variable
|
|
141
|
+
// based) — don't mock a component that doesn't exist.
|
|
140
142
|
}));
|
|
141
143
|
```
|
|
142
144
|
|
|
@@ -150,7 +152,8 @@ import "./mocks/cometchat";
|
|
|
150
152
|
|
|
151
153
|
Override specific behaviors:
|
|
152
154
|
|
|
153
|
-
```
|
|
155
|
+
```tsx
|
|
156
|
+
import { render, screen } from "@testing-library/react";
|
|
154
157
|
import { CometChat } from "@cometchat/chat-sdk-javascript";
|
|
155
158
|
|
|
156
159
|
it("shows error when login fails", async () => {
|
|
@@ -321,6 +324,12 @@ test("two users send messages back and forth", async ({ browser }) => {
|
|
|
321
324
|
|
|
322
325
|
The 10-second timeout is generous — message delivery via WebSocket is usually <500ms but CI hosts have variable latency.
|
|
323
326
|
|
|
327
|
+
> **Composer selectors (v6 DOM — for E2E only).** The example above uses role/placeholder selectors for readability, but the v6 kit (`@cometchat/chat-uikit-react@6.5.1`) renders the message input as a **`contenteditable` div, not a `<textarea>`** — driving it with `.fill()` on a placeholder/role can fail with "no input found". The reliable selectors (verified live, 2026-06-14):
|
|
328
|
+
> - input: `.cometchat-message-composer__input[contenteditable="plaintext-only"]` → focus it, then `page.keyboard.type("…")` (or `locator.fill()` works on the contenteditable in Playwright ≥1.4x)
|
|
329
|
+
> - send button: `.cometchat-message-composer__send-button`
|
|
330
|
+
>
|
|
331
|
+
> This is a **testing-only** fact about the rendered DOM — the §8.7 rule "never target internal `cometchat-*` class names for **styling**" still stands; for styling use the CSS variables. (Real-time delivery between two live clients measured ~1.0–1.3s reload-free in this setup.)
|
|
332
|
+
|
|
324
333
|
### Test users
|
|
325
334
|
|
|
326
335
|
CometChat dev mode pre-seeds five test users (`cometchat-uid-1` through `cometchat-uid-5`). Use them in e2e — never create new users in the test app via `Auth Key` flows that leak credentials.
|