@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.
Files changed (233) hide show
  1. package/LICENSE +21 -0
  2. package/bin/install.js +27 -0
  3. package/package.json +14 -1
  4. package/skills/cometchat/SKILL.md +233 -69
  5. package/skills/cometchat/references/asking-questions.md +48 -0
  6. package/skills/cometchat-a11y/SKILL.md +3 -2
  7. package/skills/cometchat-android-v5/SKILL.md +2 -1
  8. package/skills/cometchat-android-v5-calls/SKILL.md +36 -22
  9. package/skills/cometchat-android-v5-calls/references/README.md +1 -1
  10. package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +7 -5
  11. package/skills/cometchat-android-v5-calls/references/audio-controls.md +4 -4
  12. package/skills/cometchat-android-v5-calls/references/call-layouts.md +33 -25
  13. package/skills/cometchat-android-v5-calls/references/call-session.md +2 -2
  14. package/skills/cometchat-android-v5-calls/references/custom-ui.md +5 -5
  15. package/skills/cometchat-android-v5-calls/references/event-listeners.md +2 -2
  16. package/skills/cometchat-android-v5-calls/references/idle-timeout.md +20 -14
  17. package/skills/cometchat-android-v5-calls/references/in-call-chat.md +1 -1
  18. package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +43 -27
  19. package/skills/cometchat-android-v5-calls/references/participant-management.md +3 -3
  20. package/skills/cometchat-android-v5-calls/references/raise-hand.md +25 -19
  21. package/skills/cometchat-android-v5-calls/references/recording.md +2 -2
  22. package/skills/cometchat-android-v5-calls/references/ringing-integration.md +1 -1
  23. package/skills/cometchat-android-v5-calls/references/screen-sharing.md +5 -9
  24. package/skills/cometchat-android-v5-calls/references/session-settings.md +3 -3
  25. package/skills/cometchat-android-v5-calls/references/setup.md +1 -1
  26. package/skills/cometchat-android-v5-calls/references/share-invite.md +9 -4
  27. package/skills/cometchat-android-v5-calls/references/video-controls.md +4 -4
  28. package/skills/cometchat-android-v5-calls/references/voip-calling.md +2 -2
  29. package/skills/cometchat-android-v5-components/SKILL.md +4 -3
  30. package/skills/cometchat-android-v5-core/SKILL.md +5 -3
  31. package/skills/cometchat-android-v5-customization/SKILL.md +171 -7
  32. package/skills/cometchat-android-v5-extensions/SKILL.md +7 -4
  33. package/skills/cometchat-android-v5-features/SKILL.md +5 -4
  34. package/skills/cometchat-android-v5-placement/SKILL.md +2 -1
  35. package/skills/cometchat-android-v5-production/SKILL.md +2 -1
  36. package/skills/cometchat-android-v5-push/SKILL.md +2 -3
  37. package/skills/cometchat-android-v5-testing/SKILL.md +2 -1
  38. package/skills/cometchat-android-v5-theming/SKILL.md +2 -1
  39. package/skills/cometchat-android-v5-troubleshooting/SKILL.md +3 -2
  40. package/skills/cometchat-android-v6/SKILL.md +2 -1
  41. package/skills/cometchat-android-v6-builder-settings/SKILL.md +11 -7
  42. package/skills/cometchat-android-v6-calls/SKILL.md +79 -18
  43. package/skills/cometchat-android-v6-calls/references/advanced-features.md +87 -0
  44. package/skills/cometchat-android-v6-calls/references/call-layouts.md +24 -15
  45. package/skills/cometchat-android-v6-calls/references/call-session.md +2 -2
  46. package/skills/cometchat-android-v6-calls/references/device-management.md +17 -16
  47. package/skills/cometchat-android-v6-calls/references/idle-timeout.md +7 -4
  48. package/skills/cometchat-android-v6-calls/references/in-call-chat.md +13 -8
  49. package/skills/cometchat-android-v6-calls/references/raise-hand.md +6 -4
  50. package/skills/cometchat-android-v6-compose-components/SKILL.md +52 -29
  51. package/skills/cometchat-android-v6-compose-customization/SKILL.md +156 -1
  52. package/skills/cometchat-android-v6-compose-placement/SKILL.md +129 -40
  53. package/skills/cometchat-android-v6-compose-theming/SKILL.md +27 -1
  54. package/skills/cometchat-android-v6-core/SKILL.md +208 -28
  55. package/skills/cometchat-android-v6-events/SKILL.md +4 -1
  56. package/skills/cometchat-android-v6-extensions/SKILL.md +2 -1
  57. package/skills/cometchat-android-v6-features/SKILL.md +26 -2
  58. package/skills/cometchat-android-v6-kotlin-components/SKILL.md +31 -1
  59. package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +172 -1
  60. package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +20 -5
  61. package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +36 -5
  62. package/skills/cometchat-android-v6-migration/SKILL.md +44 -42
  63. package/skills/cometchat-android-v6-production/SKILL.md +6 -3
  64. package/skills/cometchat-android-v6-push/SKILL.md +43 -2
  65. package/skills/cometchat-android-v6-testing/SKILL.md +11 -8
  66. package/skills/cometchat-android-v6-troubleshooting/SKILL.md +26 -5
  67. package/skills/cometchat-angular-calls/SKILL.md +256 -389
  68. package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +3 -2
  69. package/skills/cometchat-angular-calls/references/call-layouts.md +29 -12
  70. package/skills/cometchat-angular-calls/references/call-session.md +2 -2
  71. package/skills/cometchat-angular-calls/references/custom-ui.md +18 -10
  72. package/skills/cometchat-angular-calls/references/device-management.md +53 -34
  73. package/skills/cometchat-angular-calls/references/group-calls.md +45 -24
  74. package/skills/cometchat-angular-calls/references/idle-timeout.md +31 -15
  75. package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +7 -6
  76. package/skills/cometchat-angular-calls/references/raise-hand.md +9 -4
  77. package/skills/cometchat-angular-calls/references/recording-screen-share.md +32 -39
  78. package/skills/cometchat-angular-calls/references/ringing-integration.md +3 -1
  79. package/skills/cometchat-angular-calls/references/share-invite.md +11 -5
  80. package/skills/cometchat-angular-calls/references/virtual-background.md +29 -0
  81. package/skills/cometchat-angular-components/SKILL.md +149 -620
  82. package/skills/cometchat-angular-core/SKILL.md +232 -312
  83. package/skills/cometchat-angular-customization/SKILL.md +415 -223
  84. package/skills/cometchat-angular-features/SKILL.md +216 -334
  85. package/skills/cometchat-angular-patterns/SKILL.md +168 -359
  86. package/skills/cometchat-angular-placement/SKILL.md +189 -560
  87. package/skills/cometchat-angular-production/SKILL.md +241 -92
  88. package/skills/cometchat-angular-push/SKILL.md +280 -294
  89. package/skills/cometchat-angular-testing/SKILL.md +430 -158
  90. package/skills/cometchat-angular-theming/SKILL.md +190 -265
  91. package/skills/cometchat-angular-troubleshooting/SKILL.md +192 -157
  92. package/skills/cometchat-astro-patterns/SKILL.md +3 -2
  93. package/skills/cometchat-calls/SKILL.md +25 -19
  94. package/skills/cometchat-calls/references/use-case-broadcast.md +15 -10
  95. package/skills/cometchat-calls/references/use-case-marketplace.md +2 -3
  96. package/skills/cometchat-calls/references/use-case-support.md +3 -4
  97. package/skills/cometchat-calls/references/use-case-team.md +23 -12
  98. package/skills/cometchat-calls/references/use-case-telehealth.md +3 -4
  99. package/skills/cometchat-components/SKILL.md +163 -25
  100. package/skills/cometchat-core/SKILL.md +258 -20
  101. package/skills/cometchat-customization/SKILL.md +50 -25
  102. package/skills/cometchat-features/SKILL.md +314 -35
  103. package/skills/cometchat-flutter-v5/SKILL.md +10 -4
  104. package/skills/cometchat-flutter-v5-calls/SKILL.md +188 -158
  105. package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +48 -24
  106. package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +20 -15
  107. package/skills/cometchat-flutter-v5-calls/references/call-session.md +100 -145
  108. package/skills/cometchat-flutter-v5-calls/references/device-management.md +12 -8
  109. package/skills/cometchat-flutter-v5-calls/references/group-calls.md +30 -36
  110. package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +15 -13
  111. package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +12 -9
  112. package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +115 -65
  113. package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +41 -30
  114. package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +17 -14
  115. package/skills/cometchat-flutter-v5-calls/references/share-invite.md +8 -2
  116. package/skills/cometchat-flutter-v5-conversations/SKILL.md +2 -1
  117. package/skills/cometchat-flutter-v5-core/SKILL.md +5 -4
  118. package/skills/cometchat-flutter-v5-customization/SKILL.md +136 -5
  119. package/skills/cometchat-flutter-v5-events/SKILL.md +2 -1
  120. package/skills/cometchat-flutter-v5-messages/SKILL.md +2 -1
  121. package/skills/cometchat-flutter-v5-production/SKILL.md +15 -6
  122. package/skills/cometchat-flutter-v5-push/SKILL.md +2 -1
  123. package/skills/cometchat-flutter-v5-testing/SKILL.md +17 -6
  124. package/skills/cometchat-flutter-v5-theming/SKILL.md +2 -1
  125. package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +7 -6
  126. package/skills/cometchat-flutter-v5-users-groups/SKILL.md +3 -2
  127. package/skills/cometchat-flutter-v6/SKILL.md +17 -16
  128. package/skills/cometchat-flutter-v6-calls/SKILL.md +72 -57
  129. package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +5 -3
  130. package/skills/cometchat-flutter-v6-calls/references/advanced-features.md +89 -0
  131. package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +15 -12
  132. package/skills/cometchat-flutter-v6-calls/references/call-session.md +2 -2
  133. package/skills/cometchat-flutter-v6-calls/references/device-management.md +9 -3
  134. package/skills/cometchat-flutter-v6-calls/references/group-calls.md +10 -10
  135. package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +15 -7
  136. package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +6 -3
  137. package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +23 -16
  138. package/skills/cometchat-flutter-v6-components/SKILL.md +32 -11
  139. package/skills/cometchat-flutter-v6-conversations/SKILL.md +39 -11
  140. package/skills/cometchat-flutter-v6-core/SKILL.md +182 -21
  141. package/skills/cometchat-flutter-v6-customization/SKILL.md +97 -25
  142. package/skills/cometchat-flutter-v6-events/SKILL.md +3 -2
  143. package/skills/cometchat-flutter-v6-features/SKILL.md +15 -6
  144. package/skills/cometchat-flutter-v6-messages/SKILL.md +111 -60
  145. package/skills/cometchat-flutter-v6-migration/SKILL.md +18 -25
  146. package/skills/cometchat-flutter-v6-placement/SKILL.md +79 -50
  147. package/skills/cometchat-flutter-v6-production/SKILL.md +13 -12
  148. package/skills/cometchat-flutter-v6-push/SKILL.md +41 -19
  149. package/skills/cometchat-flutter-v6-testing/SKILL.md +4 -4
  150. package/skills/cometchat-flutter-v6-theming/SKILL.md +38 -5
  151. package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +182 -17
  152. package/skills/cometchat-flutter-v6-users-groups/SKILL.md +12 -4
  153. package/skills/cometchat-i18n/SKILL.md +140 -79
  154. package/skills/cometchat-ios/SKILL.md +4 -2
  155. package/skills/cometchat-ios-calls/SKILL.md +225 -95
  156. package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +11 -9
  157. package/skills/cometchat-ios-calls/references/audio-modes-and-controls.md +45 -0
  158. package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +6 -7
  159. package/skills/cometchat-ios-calls/references/call-layouts.md +31 -91
  160. package/skills/cometchat-ios-calls/references/call-session.md +51 -54
  161. package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +33 -29
  162. package/skills/cometchat-ios-calls/references/custom-ui.md +38 -38
  163. package/skills/cometchat-ios-calls/references/group-calls.md +33 -70
  164. package/skills/cometchat-ios-calls/references/idle-timeout.md +24 -25
  165. package/skills/cometchat-ios-calls/references/in-call-chat.md +19 -23
  166. package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +128 -70
  167. package/skills/cometchat-ios-calls/references/picture-in-picture.md +20 -20
  168. package/skills/cometchat-ios-calls/references/raise-hand.md +14 -227
  169. package/skills/cometchat-ios-calls/references/recording-screen-share.md +35 -122
  170. package/skills/cometchat-ios-calls/references/ringing-integration.md +17 -16
  171. package/skills/cometchat-ios-calls/references/share-invite.md +8 -12
  172. package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +4 -4
  173. package/skills/cometchat-ios-components/SKILL.md +200 -12
  174. package/skills/cometchat-ios-core/SKILL.md +173 -45
  175. package/skills/cometchat-ios-customization/SKILL.md +276 -110
  176. package/skills/cometchat-ios-features/SKILL.md +64 -36
  177. package/skills/cometchat-ios-placement/SKILL.md +15 -12
  178. package/skills/cometchat-ios-production/SKILL.md +12 -4
  179. package/skills/cometchat-ios-push/SKILL.md +53 -19
  180. package/skills/cometchat-ios-testing/SKILL.md +14 -9
  181. package/skills/cometchat-ios-theming/SKILL.md +39 -3
  182. package/skills/cometchat-ios-troubleshooting/SKILL.md +41 -21
  183. package/skills/cometchat-native-bare-patterns/SKILL.md +36 -19
  184. package/skills/cometchat-native-calls/SKILL.md +29 -17
  185. package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +2 -2
  186. package/skills/cometchat-native-calls/references/call-layouts.md +15 -14
  187. package/skills/cometchat-native-calls/references/call-session.md +2 -2
  188. package/skills/cometchat-native-calls/references/custom-ui.md +12 -8
  189. package/skills/cometchat-native-calls/references/device-management.md +53 -30
  190. package/skills/cometchat-native-calls/references/group-calls.md +35 -30
  191. package/skills/cometchat-native-calls/references/idle-timeout.md +6 -6
  192. package/skills/cometchat-native-calls/references/in-call-chat.md +10 -8
  193. package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +2 -2
  194. package/skills/cometchat-native-calls/references/raise-hand.md +15 -13
  195. package/skills/cometchat-native-calls/references/recording-screen-share.md +49 -170
  196. package/skills/cometchat-native-calls/references/share-invite.md +7 -5
  197. package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +4 -2
  198. package/skills/cometchat-native-components/SKILL.md +84 -52
  199. package/skills/cometchat-native-core/SKILL.md +102 -33
  200. package/skills/cometchat-native-customization/SKILL.md +150 -28
  201. package/skills/cometchat-native-expo-patterns/SKILL.md +60 -29
  202. package/skills/cometchat-native-features/SKILL.md +24 -17
  203. package/skills/cometchat-native-placement/SKILL.md +19 -10
  204. package/skills/cometchat-native-production/SKILL.md +9 -3
  205. package/skills/cometchat-native-push/SKILL.md +2 -1
  206. package/skills/cometchat-native-testing/SKILL.md +1 -2
  207. package/skills/cometchat-native-theming/SKILL.md +54 -29
  208. package/skills/cometchat-native-troubleshooting/SKILL.md +11 -5
  209. package/skills/cometchat-nextjs-patterns/SKILL.md +22 -8
  210. package/skills/cometchat-placement/SKILL.md +42 -3
  211. package/skills/cometchat-production/SKILL.md +12 -5
  212. package/skills/cometchat-react-calls/SKILL.md +220 -10
  213. package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +4 -3
  214. package/skills/cometchat-react-calls/references/call-layouts.md +5 -6
  215. package/skills/cometchat-react-calls/references/call-session.md +1 -1
  216. package/skills/cometchat-react-calls/references/custom-ui.md +61 -15
  217. package/skills/cometchat-react-calls/references/device-management.md +55 -51
  218. package/skills/cometchat-react-calls/references/group-calls.md +18 -23
  219. package/skills/cometchat-react-calls/references/idle-timeout.md +25 -12
  220. package/skills/cometchat-react-calls/references/in-call-chat.md +7 -7
  221. package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +9 -11
  222. package/skills/cometchat-react-calls/references/raise-hand.md +14 -14
  223. package/skills/cometchat-react-calls/references/recording-screen-share.md +39 -38
  224. package/skills/cometchat-react-calls/references/ringing-integration.md +2 -2
  225. package/skills/cometchat-react-calls/references/share-invite.md +4 -5
  226. package/skills/cometchat-react-calls/references/testing-calls-on-web.md +20 -2
  227. package/skills/cometchat-react-calls/references/virtual-background.md +32 -0
  228. package/skills/cometchat-react-patterns/SKILL.md +45 -5
  229. package/skills/cometchat-react-push/SKILL.md +258 -72
  230. package/skills/cometchat-react-router-patterns/SKILL.md +12 -6
  231. package/skills/cometchat-react-testing/SKILL.md +14 -5
  232. package/skills/cometchat-theming/SKILL.md +181 -18
  233. package/skills/cometchat-troubleshooting/SKILL.md +40 -20
@@ -1,403 +1,389 @@
1
1
  ---
2
2
  name: cometchat-angular-push
3
- description: Push notifications for CometChat Angular UI Kit v4 in Angular 12-15 projects. Web doesn't have native push covers @angular/service-worker setup, ngsw-config.json, SwPush subscription, server-side webhook to send pushes, click-through routing via Angular Router, Angular Universal SSR considerations, and HTTPS requirements.
3
+ description: Push notifications for CometChat Angular UI Kit v5 (@cometchat/chat-uikit-angular@5) web push via Firebase Cloud Messaging (FCM) + the CometChat Notifications API. Covers dashboard FCM provider setup, the firebase-messaging-sw.js service worker, Notification permission, getting the FCM token, registering it with CometChatNotifications.registerPushToken + PushPlatforms.FCM_WEB AFTER login, an Angular PushService, environment config, foreground vs background handling, click-through routing, and logout cleanup.
4
4
  license: "MIT"
5
- compatibility: "Angular 12-15 (LTS focus on 15); @angular/service-worker (matched to Angular major); Web Push API (Chrome 50+, Firefox 44+, Edge 17+, Safari 16+ desktop, Safari 16.4+ iOS PWA-only); HTTPS required"
6
- allowed-tools: "shell, file-read, file-search, file-list, ask-user"
5
+ compatibility: "Angular >=17 <22; @cometchat/chat-uikit-angular ^5.0; @cometchat/chat-sdk-javascript ^4.1"
7
6
  metadata:
8
7
  author: "CometChat"
9
8
  version: "4.0.0"
10
- tags: "cometchat angular web push notifications service-worker swpush ngsw vapid universal ssr"
9
+ tags: "cometchat angular web push notifications fcm firebase service-worker registerPushToken PushPlatforms notifications-api standalone v5"
11
10
  ---
12
11
 
13
12
  ## Purpose
14
13
 
15
- Web Push for Angular CometChat integrations. Angular's `@angular/service-worker` package provides `SwPush` a thin wrapper over the Push API — that integrates with Angular's DI tree and Router, so it's the recommended path over hand-rolled Service Workers.
14
+ Web push for CometChat **Angular UI Kit v5** (`@cometchat/chat-uikit-angular@5`). On the web, CometChat push runs through **Firebase Cloud Messaging (FCM)** plus the **CometChat Notifications API**CometChat hosts the send path. You do NOT build your own push server or webhook for the basic flow: configure an FCM provider in the CometChat dashboard, register the browser's FCM token with `CometChatNotifications.registerPushToken(...)`, and CometChat delivers a push whenever a message arrives for that user.
16
15
 
17
- **Read these other skills first:**
18
- - `cometchat-angular-core` — UIKitSettingsBuilder, login order
19
- - `cometchat-angular-patterns` — module setup
20
- - `cometchat-react-push` — same Web Push spec, React-flavored explanation; shared concepts (VAPID, server-side webhook, iOS PWA caveat) covered there in depth
16
+ This is the v5 (standalone, Angular 17–21) rewrite. The previous v4 skill used `@angular/service-worker` + `SwPush` + a self-hosted VAPID web-push server + a CometChat webhook. **That hand-rolled path is replaced** — v5 uses FCM end-to-end through the CometChat Notifications API, which is the documented, supported web-push path.
21
17
 
22
- **Ground truth:**
23
- - `@angular/service-worker` — https://angular.io/guide/service-worker-intro
24
- - `SwPush` API https://angular.io/api/service-worker/SwPush
25
- - Web Push spec https://datatracker.ietf.org/doc/html/rfc8030
18
+ **Read these skills first:**
19
+ - `cometchat-angular-core` — `UIKitSettingsBuilder` init, Promise-based `login(uid)` (bare string), `loggedInUser$`, environment config. Push registration hangs off the same login lifecycle.
20
+ - `cometchat-react-push` is the React sibling for the *self-hosted* Web Push model; the FCM + `CometChatNotifications` plumbing in THIS skill is the shared web SDK API and is the recommended path for both. Where they differ, this skill wins for Angular.
21
+ - `cometchat-angular-production` server-minted auth tokens (push registration is tied to the logged-in auth token).
26
22
 
27
- ---
28
-
29
- ## 1. Architecture (same as web)
23
+ **Ground truth (verify before relying on any symbol):** **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).
24
+ - Chat SDK types: `node_modules/@cometchat/chat-sdk-javascript/CometChat.d.ts` — `CometChatNotifications`, `PushPlatforms`.
25
+ - FCM (web): https://firebase.google.com/docs/cloud-messaging/js/client
26
+ - CometChat dashboard → **Notifications** → **Push Notifications** (FCM provider config).
30
27
 
31
- Same shape as `cometchat-react-push`: client SW + push server + CometChat webhook. Angular's `SwPush` is the client-side primitive; everything else is the same.
28
+ > The Chat SDK is `@cometchat/chat-sdk-javascript@^4.1`. The web push API documented below is its **real** notification API `CometChatNotifications.registerPushToken`, `PushPlatforms.FCM_WEB`, `CometChatNotifications.unregisterPushToken`. Do not substitute mobile-only symbols (APNs, FCM_ANDROID, etc.) the only web platform enum value is `FCM_WEB`.
32
29
 
33
30
  ---
34
31
 
35
- ## 2. Add @angular/service-worker
32
+ ## 1. Architecture
36
33
 
37
- ```bash
38
- ng add @angular/service-worker
39
34
  ```
40
-
41
- This:
42
- - Adds `@angular/service-worker` to dependencies
43
- - Creates `ngsw-config.json` at project root
44
- - Imports `ServiceWorkerModule.register('ngsw-worker.js', ...)` in `AppModule`
45
- - Sets `serviceWorker: true` in `angular.json` build options
46
-
47
- Verify in `app.module.ts`:
48
-
49
- ```ts
50
- @NgModule({
51
- imports: [
52
- BrowserModule,
53
- ServiceWorkerModule.register('ngsw-worker.js', {
54
- enabled: !isDevMode(), // SW disabled in dev mode by default
55
- registrationStrategy: 'registerWhenStable:30000',
56
- }),
57
- ],
58
- })
59
- export class AppModule {}
35
+ Browser (your Angular app)
36
+ ├── Firebase JS SDK (firebase/messaging) — gets the FCM registration token
37
+ ├── firebase-messaging-sw.js — service worker; receives background push
38
+ └── Notification permission — granted by the user
39
+
40
+ CometChat backend
41
+ ├── FCM provider config (server key / service account) ← set in dashboard
42
+ └── Notifications service — sends an FCM push to the user's registered token(s)
43
+ whenever a message arrives for them
44
+
45
+ Your Angular code
46
+ └── After login → get FCM token → CometChatNotifications.registerPushToken(token, FCM_WEB)
60
47
  ```
61
48
 
49
+ You own: the Firebase project, the service worker file, the permission prompt, token registration after login, and token cleanup on logout. CometChat owns the actual send. No self-hosted push server, no VAPID web-push library, no CometChat webhook for the basic flow.
50
+
62
51
  ---
63
52
 
64
- ## 3. ngsw-config.jsonminimal config for chat push
53
+ ## 2. Dashboardenable the FCM push provider (one-time)
65
54
 
66
- The default config caches assets for offline-first PWAs. For chat push, you mostly need the data-sources for live API calls:
55
+ In the CometChat dashboard:
67
56
 
68
- ```json
69
- {
70
- "$schema": "./node_modules/@angular/service-worker/config/schema.json",
71
- "index": "/index.html",
72
- "assetGroups": [
73
- {
74
- "name": "app",
75
- "installMode": "prefetch",
76
- "resources": {
77
- "files": ["/favicon.ico", "/index.html", "/manifest.webmanifest", "/*.css", "/*.js"]
78
- }
79
- },
80
- {
81
- "name": "assets",
82
- "installMode": "lazy",
83
- "updateMode": "prefetch",
84
- "resources": {
85
- "files": ["/assets/**", "/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)"]
86
- }
87
- }
88
- ],
89
- "dataGroups": [
90
- {
91
- "name": "cometchat-api",
92
- "urls": ["https://api-*.cometchat.io/**"],
93
- "cacheConfig": {
94
- "maxSize": 100,
95
- "maxAge": "0d",
96
- "strategy": "freshness"
97
- }
98
- }
99
- ]
100
- }
101
- ```
57
+ 1. **Notifications** → **Push Notifications** → enable.
58
+ 2. Add a **provider** of type **FCM**.
59
+ 3. Supply your Firebase credentials. Modern FCM (HTTP v1) wants the **service-account JSON** (from Firebase Console → Project settings → Service accounts → Generate new private key). Older configs accept the legacy **Server Key** + **Sender ID** (Cloud Messaging tab). Match whatever the dashboard's FCM form currently asks for.
60
+ 4. Note the **Provider ID** you assign (default is `default`). You pass this same string as the third arg to `registerPushToken` if you used a non-default provider.
102
61
 
103
- **Don't cache CometChat API responses** — they're real-time. The freshness strategy with `maxAge: "0d"` effectively disables caching.
62
+ The Firebase **web app config** (`apiKey`, `authDomain`, `projectId`, `messagingSenderId`, `appId`) and the **VAPID key pair** (Firebase Console → Cloud Messaging → Web configuration → "Web Push certificates") are client-side — they go in `environment.ts` (§4). The service-account JSON / Server Key is **server-side only** — it lives in the CometChat dashboard, never in your Angular bundle.
104
63
 
105
64
  ---
106
65
 
107
- ## 4. SwPush registration
66
+ ## 3. Install Firebase + add the service worker
108
67
 
109
- ```ts
110
- // services/push.service.ts
111
- import { Injectable } from "@angular/core";
112
- import { SwPush } from "@angular/service-worker";
113
- import { Router } from "@angular/router";
114
- import { environment } from "../../environments/environment";
115
-
116
- @Injectable({ providedIn: "root" })
117
- export class PushService {
118
- constructor(private swPush: SwPush, private router: Router) {
119
- // Listen for notification clicks — fired when user taps a push notification
120
- this.swPush.notificationClicks.subscribe(({ notification }) => {
121
- const data = notification.data;
122
- const targetUrl = data.receiverType === "group"
123
- ? `/messages/group/${data.conversationId}`
124
- : `/messages/user/${data.senderUid}`;
125
- this.router.navigateByUrl(targetUrl);
126
- });
127
- }
68
+ ```bash
69
+ npm install firebase
70
+ ```
128
71
 
129
- async subscribe(uid: string): Promise<void> {
130
- if (!this.swPush.isEnabled) {
131
- console.warn("SwPush not enabled — Service Worker not registered or not supported");
132
- return;
133
- }
72
+ > Do **not** use `@angular/service-worker` / `SwPush` for CometChat web push — FCM ships its own service worker contract (`firebase-messaging-sw.js`) and the Firebase JS SDK manages the token. The v4 `ngsw` path is gone.
134
73
 
135
- try {
136
- const subscription = await this.swPush.requestSubscription({
137
- serverPublicKey: environment.vapidPublic,
138
- });
139
-
140
- // Send to YOUR push server, keyed by uid
141
- await fetch("/api/push/subscribe", {
142
- method: "POST",
143
- headers: { "Content-Type": "application/json" },
144
- body: JSON.stringify({ uid, subscription }),
145
- });
146
- } catch (err) {
147
- // User denied permission, or push not supported
148
- console.warn("Web Push subscription failed:", err);
149
- }
150
- }
74
+ ### `src/firebase-messaging-sw.js`
151
75
 
152
- async unsubscribe(uid: string): Promise<void> {
153
- if (!this.swPush.isEnabled) return;
154
- const subscription = await this.swPush.subscription.toPromise();
155
- if (!subscription) return;
76
+ This file MUST be served from the origin root (`/firebase-messaging-sw.js`) — `firebase.messaging()` registers it by that exact path. Add it as an Angular asset so the build copies it to the output root.
156
77
 
157
- await fetch("/api/push/unsubscribe", {
158
- method: "POST",
159
- headers: { "Content-Type": "application/json" },
160
- body: JSON.stringify({ uid, subscription }),
161
- });
162
- await this.swPush.unsubscribe();
163
- }
164
- }
165
- ```
78
+ ```js
79
+ // src/firebase-messaging-sw.js
80
+ // Loaded by the browser as a service worker — runs OUTSIDE Angular.
81
+ // Use the compat builds; ES module imports are not available in classic SWs.
82
+ importScripts("https://www.gstatic.com/firebasejs/10.12.0/firebase-app-compat.js");
83
+ importScripts("https://www.gstatic.com/firebasejs/10.12.0/firebase-messaging-compat.js");
166
84
 
167
- **Permission gesture rule:** `requestSubscription` triggers the browser's permission prompt. Browsers require this in response to a user gesture (click). Don't call this from `OnInit` — wire it to a button click.
85
+ firebase.initializeApp({
86
+ apiKey: "YOUR_FIREBASE_API_KEY",
87
+ authDomain: "YOUR_PROJECT.firebaseapp.com",
88
+ projectId: "YOUR_PROJECT_ID",
89
+ messagingSenderId: "YOUR_SENDER_ID",
90
+ appId: "YOUR_APP_ID",
91
+ });
168
92
 
169
- ---
93
+ const messaging = firebase.messaging();
94
+
95
+ // Background handler — fires when the tab is closed/backgrounded.
96
+ messaging.onBackgroundMessage((payload) => {
97
+ const title = payload.notification?.title ?? payload.data?.senderName ?? "New message";
98
+ self.registration.showNotification(title, {
99
+ body: payload.notification?.body ?? payload.data?.text ?? "",
100
+ icon: payload.notification?.icon ?? "/assets/chat-icon.png",
101
+ tag: payload.data?.conversationId, // dedupe per conversation
102
+ data: payload.data ?? {}, // carried into notificationclick
103
+ });
104
+ });
170
105
 
171
- ## 5. Wire into the auth flow
106
+ // Click-through focus an open tab or open a new one, deep-linking to the thread.
107
+ self.addEventListener("notificationclick", (event) => {
108
+ event.notification.close();
109
+ const data = event.notification.data || {};
110
+ const url = data.receiverType === "group"
111
+ ? `/messages/group/${data.conversationId}`
112
+ : `/messages/user/${data.sender}`;
113
+ event.waitUntil(
114
+ clients.matchAll({ type: "window", includeUncontrolled: true }).then((wins) => {
115
+ for (const w of wins) {
116
+ if ("focus" in w) { w.focus(); w.postMessage({ type: "open_conversation", ...data }); return; }
117
+ }
118
+ return clients.openWindow(url);
119
+ })
120
+ );
121
+ });
122
+ ```
172
123
 
173
- ```ts
174
- // services/auth.service.ts (or wherever login happens)
175
- import { PushService } from "./push.service";
124
+ > The `payload.data` keys (`conversationId`, `sender`, `receiverType`, `text`, `senderName`) are whatever CometChat's FCM payload carries — confirm the exact field names against a real push in DevTools → Application → Service Workers, and adjust. Do not assume; CometChat's data-payload shape is the source of truth.
176
125
 
177
- @Injectable({ providedIn: "root" })
178
- export class AuthService {
179
- constructor(private pushService: PushService) {}
126
+ ### Register the SW file as an Angular asset
180
127
 
181
- async loginAndEnableChat(uid: string): Promise<void> {
182
- await CometChatUIKit.login(uid);
183
- // Don't auto-subscribe to push — let the user opt in via a button
184
- }
128
+ `angular.json` → `projects.<app>.architect.build.options.assets` (alongside the mandatory CometChat assets glob from `cometchat-angular-core` §2):
185
129
 
186
- async logout(uid: string): Promise<void> {
187
- await this.pushService.unsubscribe(uid); // CRITICAL clean up before SDK logout
188
- await CometChatUIKit.logout();
189
- }
190
- }
130
+ ```json
131
+ { "glob": "firebase-messaging-sw.js", "input": "src", "output": "/" }
191
132
  ```
192
133
 
193
- ---
134
+ Build output then serves it at `/firebase-messaging-sw.js`. Verify after `ng build` that the file is at the dist root, not under `assets/`.
194
135
 
195
- ## 6. "Enable notifications" button
136
+ ---
196
137
 
197
- ```ts
198
- // components/notification-prompt.component.ts
199
- @Component({
200
- selector: "app-notification-prompt",
201
- template: `
202
- <button (click)="enable()" *ngIf="!enabled">
203
- Enable notifications
204
- </button>
205
- `,
206
- })
207
- export class NotificationPromptComponent {
208
- enabled = false;
138
+ ## 4. Environment config
209
139
 
210
- constructor(private pushService: PushService, private auth: AuthService) {}
140
+ Angular has no `process.env`. The Firebase web config + VAPID key live in `src/environments/environment.ts` (these are publishable client values — `apiKey` here is a Firebase identifier, not a secret):
211
141
 
212
- async enable() {
213
- const user = await CometChatUIKit.getLoggedInUser();
214
- if (!user) return;
215
- await this.pushService.subscribe(user.uid);
216
- this.enabled = true;
217
- }
218
- }
142
+ ```typescript
143
+ // src/environments/environment.ts
144
+ export const environment = {
145
+ production: false,
146
+ cometchat: {
147
+ appId: "YOUR_APP_ID",
148
+ region: "us", // "us" | "eu" | "in"
149
+ authKey: "YOUR_AUTH_KEY", // dev only
150
+ },
151
+ firebase: {
152
+ apiKey: "YOUR_FIREBASE_API_KEY",
153
+ authDomain: "YOUR_PROJECT.firebaseapp.com",
154
+ projectId: "YOUR_PROJECT_ID",
155
+ messagingSenderId: "YOUR_SENDER_ID",
156
+ appId: "YOUR_FIREBASE_APP_ID",
157
+ vapidKey: "YOUR_WEB_PUSH_CERTIFICATE_KEY_PAIR", // FCM → Web configuration
158
+ },
159
+ // Provider ID set in the dashboard (§2). Omit / "default" if you didn't change it.
160
+ cometchatPushProviderId: "default",
161
+ };
219
162
  ```
220
163
 
221
- Mount this somewhere visible chat header, settings page, or a one-time onboarding card.
164
+ Keep the same shape in `environment.prod.ts`. The CometChat **REST API Key** and the Firebase **service-account JSON** never appear in any `src/` file — Angular ships `src/` to the client.
222
165
 
223
166
  ---
224
167
 
225
- ## 7. Service Worker push event handler
168
+ ## 5. PushService get the FCM token and register it
226
169
 
227
- `@angular/service-worker` ships its own `ngsw-worker.js` that handles push events automatically — when a push arrives, it calls `ServiceWorkerRegistration.showNotification` with the push payload.
170
+ ```typescript
171
+ // src/app/services/push.service.ts
172
+ import { Injectable, Inject, PLATFORM_ID } from "@angular/core";
173
+ import { isPlatformBrowser } from "@angular/common";
174
+ import { Router } from "@angular/router";
175
+ import { initializeApp } from "firebase/app";
176
+ import { getMessaging, getToken, onMessage, deleteToken, Messaging } from "firebase/messaging";
177
+ import { CometChatNotifications } from "@cometchat/chat-sdk-javascript";
178
+ import { environment } from "../../environments/environment";
228
179
 
229
- **However**, the default behavior shows the entire payload as the notification body. For chat, you want a custom UI: sender name as title, preview as body, conversation tag for dedup.
180
+ @Injectable({ providedIn: "root" })
181
+ export class PushService {
182
+ private messaging: Messaging | null = null;
230
183
 
231
- Two paths:
184
+ constructor(
185
+ private router: Router,
186
+ @Inject(PLATFORM_ID) private platformId: object,
187
+ ) {
188
+ if (!isPlatformBrowser(this.platformId)) return; // SSR / prerender guard
189
+ if (!("serviceWorker" in navigator) || !("Notification" in window)) return;
190
+
191
+ const app = initializeApp(environment.firebase);
192
+ this.messaging = getMessaging(app);
193
+
194
+ // Foreground messages: the SW background handler does NOT fire while the tab
195
+ // is focused. Decide your own UX here (toast, in-app banner, or a manual
196
+ // Notification). Don't double-notify.
197
+ onMessage(this.messaging, (payload) => {
198
+ // e.g. show an in-app toast; skip an OS notification if the chat is focused.
199
+ console.debug("Foreground push:", payload);
200
+ });
232
201
 
233
- ### Path A Use the payload shape `ngsw-worker.js` expects
202
+ // SW app messages from notificationclick (deep-link into the thread).
203
+ navigator.serviceWorker?.addEventListener("message", (event: MessageEvent) => {
204
+ const d = event.data;
205
+ if (d?.type === "open_conversation") {
206
+ const url = d.receiverType === "group"
207
+ ? `/messages/group/${d.conversationId}`
208
+ : `/messages/user/${d.sender}`;
209
+ this.router.navigateByUrl(url);
210
+ }
211
+ });
212
+ }
234
213
 
235
- The Angular SW expects this payload shape:
214
+ /** Call AFTER CometChatUIKit.login(uid) resolves. Must be user-gesture-initiated
215
+ * (Notification.requestPermission requires it on most browsers). */
216
+ async register(): Promise<void> {
217
+ if (!this.messaging) return;
218
+
219
+ const permission = await Notification.requestPermission();
220
+ if (permission !== "granted") return; // user declined — bail quietly
221
+
222
+ // The Firebase SDK registers /firebase-messaging-sw.js itself; pass the
223
+ // VAPID key from the FCM Web configuration.
224
+ const fcmToken = await getToken(this.messaging, { vapidKey: environment.firebase.vapidKey });
225
+ if (!fcmToken) return;
226
+
227
+ // The ONE call that wires the browser into CometChat's push pipeline.
228
+ await CometChatNotifications.registerPushToken(
229
+ fcmToken,
230
+ CometChatNotifications.PushPlatforms.FCM_WEB, // = "fcm_web" — the only web value
231
+ environment.cometchatPushProviderId, // optional; defaults to "default"
232
+ );
233
+ }
236
234
 
237
- ```json
238
- {
239
- "notification": {
240
- "title": "Alice",
241
- "body": "Hi there",
242
- "icon": "/avatars/alice.png",
243
- "tag": "chat-conversation-123",
244
- "data": {
245
- "conversationId": "conversation-123",
246
- "senderUid": "cometchat-uid-1",
247
- "receiverType": "user"
235
+ /** Call BEFORE CometChatUIKit.logout(). Order matters — registration is tied
236
+ * to the current auth token, which logout invalidates. */
237
+ async unregister(): Promise<void> {
238
+ if (!this.messaging) return;
239
+ try {
240
+ await CometChatNotifications.unregisterPushToken(); // clears CometChat-side
241
+ } finally {
242
+ await deleteToken(this.messaging).catch(() => {}); // clears the FCM token too
248
243
  }
249
244
  }
250
245
  }
251
246
  ```
252
247
 
253
- Your push server sends this exact shape. `ngsw-worker.js` extracts `notification` and shows it.
254
-
255
- ### Path BCustom Service Worker
256
-
257
- If you need behavior beyond what Angular's SW provides (e.g. checking if the chat tab is focused before notifying), eject from `ngsw-worker.js` and write a custom SW. Heavier maintenance only needed for advanced cases.
258
-
259
- ---
260
-
261
- ## 8. Server-side push send
262
-
263
- Same shape as `cometchat-react-push` Section 6. Different payload shape — Angular SW expects the wrapped `{ notification: {...} }` form:
264
-
265
- ```ts
266
- const payload = JSON.stringify({
267
- notification: {
268
- title: sender.name,
269
- body: truncate(data.text, 80),
270
- icon: sender.avatar ?? "/icons/chat.png",
271
- tag: `chat-${receiver}`,
272
- data: {
273
- conversationId: receiver,
274
- senderUid: sender.uid,
275
- receiverType: data.entityType,
276
- },
277
- },
278
- });
279
- ```
280
-
281
- The webhook setup, signature verification, and dead-subscription cleanup are identical to the React version.
282
-
283
- ---
284
-
285
- ## 9. CometChat webhook setup
248
+ **API notes (verified against the v5 Chat SDK `.d.ts`):**
249
+ - `CometChatNotifications.registerPushToken(pushToken: string, platform: PushPlatforms, providerId?: string): Promise<string>` — registers the FCM token against the **current logged-in auth token**. Third arg is optional and defaults to `"default"`.
250
+ - `PushPlatforms.FCM_WEB = "fcm_web"` the **only** web platform value in the enum. There is no web APNs/Android variant.
251
+ - `CometChatNotifications.unregisterPushToken(): Promise<string>` — unregisters the token for the current auth token. Takes **no arguments**.
252
+ - Both are static members of the **top-level** `CometChatNotifications` class import it directly: `import { CometChatNotifications } from "@cometchat/chat-sdk-javascript"`. It is NOT nested under the `CometChat` namespace (there is no `CometChat.CometChatNotifications`).
253
+ - `PushPlatforms` is itself a top-level export of the SDK; the enum is also re-exposed as a static on the class (`CometChatNotifications.PushPlatforms`). Either `PushPlatforms.FCM_WEB` (with a top-level import) or `CometChatNotifications.PushPlatforms.FCM_WEB` is valid — both resolve to `"fcm_web"`.
286
254
 
287
- Same as `cometchat-react-push` Section 7 configure in CometChat dashboard, point at your push server, copy the signing secret.
255
+ > Legacy note: the SDK also exposes the deprecated `CometChat.registerTokenForPushNotification(token, settings?)`. It predates the Notifications service. Do **not** use it for new v5 integrations — `CometChatNotifications.registerPushToken` is the current API.
288
256
 
289
257
  ---
290
258
 
291
- ## 10. Angular Universal (SSR) considerations
259
+ ## 6. Wire into the login lifecycle
292
260
 
293
- If your app uses Angular Universal:
261
+ Registration MUST happen **after** `login(uid)` resolves — `registerPushToken` binds the token to the live auth token. (See `cometchat-angular-core` §3–§4 for the init → login order; init resolves in `main.ts` before `bootstrapApplication` — the v5 canonical path; `APP_INITIALIZER` is an alternative — and login happens in your auth service / route guard.)
294
262
 
295
- ```ts
296
- // services/push.service.ts
297
- import { isPlatformBrowser } from "@angular/common";
298
- import { Inject, PLATFORM_ID } from "@angular/core";
263
+ ```typescript
264
+ // src/app/services/auth.service.ts
265
+ import { Injectable } from "@angular/core";
266
+ import { CometChatUIKit } from "@cometchat/chat-uikit-angular";
267
+ import { PushService } from "./push.service";
299
268
 
300
269
  @Injectable({ providedIn: "root" })
301
- export class PushService {
302
- constructor(
303
- private swPush: SwPush,
304
- private router: Router,
305
- @Inject(PLATFORM_ID) private platformId: object,
306
- ) {
307
- if (!isPlatformBrowser(this.platformId)) return; // skip on server
308
- this.swPush.notificationClicks.subscribe(/* ... */);
270
+ export class AuthService {
271
+ constructor(private push: PushService) {}
272
+
273
+ async login(uid: string): Promise<void> {
274
+ const existing = CometChatUIKit.getLoggedInUser(); // sync getter, capital "In"
275
+ if (!existing) {
276
+ await CometChatUIKit.login(uid); // bare string in v5
277
+ }
278
+ // Push is opt-in + gesture-gated — do NOT auto-register here.
279
+ // Call this.push.register() from a button click (see §7).
309
280
  }
310
281
 
311
- async subscribe(uid: string): Promise<void> {
312
- if (!isPlatformBrowser(this.platformId)) return;
313
- if (!this.swPush.isEnabled) return;
314
- // ...
282
+ async logout(): Promise<void> {
283
+ await this.push.unregister(); // CRITICAL: before logout
284
+ await CometChatUIKit.logout();
315
285
  }
316
286
  }
317
287
  ```
318
288
 
319
- Without these guards, the SSR build crashes at boot with `ReferenceError: ServiceWorkerRegistration is not defined`.
289
+ ---
320
290
 
321
- `@angular/service-worker` itself ships with SSR-safe stubs, but downstream code that touches `swPush.subscription` etc. needs guards.
291
+ ## 7. "Enable notifications" button (gesture requirement)
322
292
 
323
- ---
293
+ `Notification.requestPermission()` must be called from a user gesture on most browsers — calling it from `ngOnInit` is silently rejected. Wire `register()` to a click:
324
294
 
325
- ## 11. iOS Safari 16.4+ PWA-only caveat
295
+ ```typescript
296
+ // src/app/components/enable-push.component.ts
297
+ import { Component } from "@angular/core";
298
+ import { CommonModule } from "@angular/common";
299
+ import { PushService } from "../services/push.service";
300
+ import { CometChatUIKit } from "@cometchat/chat-uikit-angular";
326
301
 
327
- Same as `cometchat-react-push` Section 9 — iOS Web Push works ONLY for sites added to the Home Screen as PWAs. Angular CLI generates `manifest.webmanifest` automatically when you `ng add @angular/pwa`; verify it's present and correct:
302
+ @Component({
303
+ selector: "app-enable-push",
304
+ standalone: true,
305
+ imports: [CommonModule],
306
+ template: `
307
+ <button *ngIf="!enabled" (click)="enable()">Enable notifications</button>
308
+ `,
309
+ })
310
+ export class EnablePushComponent {
311
+ enabled = Notification.permission === "granted";
328
312
 
329
- ```json
330
- {
331
- "name": "Your App",
332
- "short_name": "YourApp",
333
- "theme_color": "#1976d2",
334
- "background_color": "#fafafa",
335
- "display": "standalone",
336
- "start_url": "/",
337
- "icons": [/* ... */]
313
+ constructor(private push: PushService) {}
314
+
315
+ async enable(): Promise<void> {
316
+ if (!CometChatUIKit.getLoggedInUser()) return; // must be logged in first
317
+ await this.push.register();
318
+ this.enabled = Notification.permission === "granted";
319
+ }
338
320
  }
339
321
  ```
340
322
 
341
- iOS users must use Safari Share "Add to Home Screen" once for Web Push to work.
323
+ Mount it in the chat header, a settings page, or a one-time onboarding card.
342
324
 
343
325
  ---
344
326
 
345
- ## 12. HTTPS requirement
327
+ ## 8. Foreground vs background
346
328
 
347
- Service Workers + Push API both require HTTPS (or `localhost`). `ng serve --ssl` works for local HTTPS dev.
329
+ - **Background / tab closed:** `onBackgroundMessage` in `firebase-messaging-sw.js` fires; you call `showNotification` (§3).
330
+ - **Foreground / tab focused:** the SW handler does **not** fire. `onMessage` in `PushService` fires instead (§5). Show an in-app toast/banner, or skip entirely if the relevant conversation is already on screen — never both, or the user sees a duplicate. CometChat's UI Kit already updates the message list live when the tab is focused, so a silent foreground handler is often the right call.
348
331
 
349
- For production: Vercel / Netlify / Cloudflare Pages / Firebase Hosting all default to HTTPS.
332
+ ---
333
+
334
+ ## 9. Notification permission states
335
+
336
+ `Notification.permission` is `"default"` (not yet asked), `"granted"`, or `"denied"`. Once `"denied"`, you cannot re-prompt programmatically — the user must change it in browser site settings. Reflect this in the UI: show the enable button only when `permission === "default"`, and a "notifications blocked — enable in browser settings" hint when `"denied"`.
350
337
 
351
338
  ---
352
339
 
353
- ## 13. Build + deploy
340
+ ## 10. HTTPS requirement
354
341
 
355
- `@angular/service-worker` generates `ngsw-worker.js` at build time:
342
+ Service Workers, the Push API, and FCM all require **HTTPS** (or `http://localhost` for dev). On a LAN IP or plain `http://`, `getToken` and SW registration fail. Use `ng serve` (localhost is allowed) or `ng serve --ssl` for HTTPS-in-dev. Production hosts (Vercel / Netlify / Cloudflare Pages / Firebase Hosting) are HTTPS by default.
356
343
 
357
- ```bash
358
- ng build --configuration production
359
- ```
344
+ ---
360
345
 
361
- Output: `dist/your-app/ngsw-worker.js` + `dist/your-app/ngsw.json` (the SW config baked in).
346
+ ## 11. SSR / prerender (Angular Universal)
362
347
 
363
- Deploy these files alongside `index.html`. The SW updates automatically when `ngsw.json` changes (a hash of all included assets); users get the new SW on next page load.
348
+ If the app uses SSR or prerendering, every Firebase/Notification touch must be browser-guarded — the `PushService` constructor already short-circuits with `isPlatformBrowser` (§5). Without it, `initializeApp` / `navigator.serviceWorker` throw `ReferenceError` at server boot. Keep all `firebase/messaging` access behind that guard; never call `register()` from server-rendered code paths.
364
349
 
365
350
  ---
366
351
 
367
- ## 14. Anti-patterns
352
+ ## 12. Anti-patterns
368
353
 
369
- 1. **Calling `swPush.requestSubscription()` from `ngOnInit`.** Browsers reject permission requests not tied to user gestures. Wire to a button click.
370
- 2. **Subscribing on `OnInit` of a lazy module.** Lazy modules instantiate after navigation; user has already missed pushes during navigation. Subscribe in eager AppModule.
371
- 3. **Sending the Auth Key in push payloads.** Visible in the Service Worker. Use the user's UID as a key into your server.
372
- 4. **Skipping the SSR guard** in Angular Universal projects. SSR boot crashes.
373
- 5. **Not unsubscribing on logout.** Previous user keeps getting notifications for the new user's messages.
374
- 6. **Hardcoding the VAPID public key in `environment.ts`.** It's not secret (it's "public"), but rotate-able is better read from runtime config.
375
- 7. **Using `*ngIf="enabled"` based on a local boolean** instead of `swPush.subscription` observable. Multi-tab scenarios get out of sync.
354
+ 1. **Registering the token before login resolves.** `registerPushToken` ties the token to the current auth token call it only after `CometChatUIKit.login(uid)` succeeds.
355
+ 2. **Calling `Notification.requestPermission()` from `ngOnInit`.** Browsers reject permission requests not tied to a user gesture. Use a clicked button (§7).
356
+ 3. **Using `@angular/service-worker` / `SwPush`.** That was the v4 path. v5 web push uses Firebase's own `firebase-messaging-sw.js` + the FCM token the two SW systems conflict if both register.
357
+ 4. **Inventing platform enum values.** The only web value is `PushPlatforms.FCM_WEB` (`"fcm_web"`). There is no `FCM_ANDROID`/`APNS` for web.
358
+ 5. **Using the deprecated `registerTokenForPushNotification`.** It predates the Notifications service; use `CometChatNotifications.registerPushToken`.
359
+ 6. **Putting the Firebase service-account JSON / CometChat REST API Key in `environment.ts`.** Those are server-only (dashboard). The Firebase web config + VAPID key are the only push values that belong client-side.
360
+ 7. **Serving `firebase-messaging-sw.js` from `/assets/`.** It must be at the origin root (`/firebase-messaging-sw.js`) or Firebase can't register it.
361
+ 8. **Not unregistering on logout.** The previous user keeps receiving pushes. Call `unregisterPushToken()` (+ `deleteToken`) before `CometChatUIKit.logout()`.
362
+ 9. **Double-notifying in the foreground.** `onMessage` and the SW `onBackgroundMessage` are mutually exclusive by tab focus — don't manually `showNotification` from foreground on top of the SW.
363
+ 10. **No SSR guard in a Universal app.** `initializeApp` at server boot throws. Guard with `isPlatformBrowser`.
376
364
 
377
365
  ---
378
366
 
379
- ## 15. Verification checklist
380
-
381
- - [ ] `@angular/service-worker` installed via `ng add`
382
- - [ ] `ngsw-config.json` exists and excludes CometChat API from caching
383
- - [ ] `ServiceWorkerModule.register('ngsw-worker.js', { enabled: !isDevMode() })` in AppModule
384
- - [ ] `PushService` injects `SwPush`
385
- - [ ] `swPush.notificationClicks.subscribe` routes to the conversation
386
- - [ ] VAPID public key in `environment.ts`; private key in server env (NOT client)
387
- - [ ] Subscribe via a user-clicked button, not OnInit
388
- - [ ] Subscription registered AFTER login resolves
389
- - [ ] Logout unsubscribes BEFORE `CometChatUIKit.logout()`
390
- - [ ] Server sends `{ notification: {...} }` payload shape (Angular SW format)
391
- - [ ] CometChat dashboard webhook configured + signature verified
367
+ ## 13. Verification checklist
368
+
369
+ - [ ] Dashboard: **Notifications → Push Notifications** enabled with an **FCM** provider; service-account JSON (or Server Key) supplied server-side
370
+ - [ ] `firebase` installed; `firebase-messaging-sw.js` in `src/`, registered as an Angular asset, served at `/firebase-messaging-sw.js` after build
371
+ - [ ] Firebase web config + VAPID key in `environment.ts`; service-account JSON / REST API Key NOT in any `src/` file
372
+ - [ ] `PushService` guards on `isPlatformBrowser` + `"serviceWorker" in navigator`
373
+ - [ ] `Notification.requestPermission()` fired from a user gesture (button), not `ngOnInit`
374
+ - [ ] FCM token fetched via `getToken(messaging, { vapidKey })`
375
+ - [ ] Token registered with `CometChatNotifications.registerPushToken(token, PushPlatforms.FCM_WEB, providerId)` **after** `login(uid)` resolves
376
+ - [ ] `onMessage` foreground handler defined; does not double-notify with the SW
377
+ - [ ] `onBackgroundMessage` + `notificationclick` in the SW deep-link to the conversation
378
+ - [ ] Logout calls `unregisterPushToken()` (+ `deleteToken`) BEFORE `CometChatUIKit.logout()`
392
379
  - [ ] HTTPS or localhost only
393
- - [ ] `manifest.webmanifest` present for iOS PWA support
394
- - [ ] Angular Universal: `isPlatformBrowser` guards in PushService
380
+ - [ ] SSR projects keep all `firebase/messaging` access behind the browser guard
395
381
 
396
382
  ---
397
383
 
398
- ## 16. Pointers
384
+ ## 14. Pointers
399
385
 
400
- - `cometchat-react-push` — sister skill; covers VAPID, server-side webhook, iOS PWA caveat in depth
401
- - `cometchat-angular-core` — login order
402
- - `cometchat-angular-patterns` — module setup, lazy loading
403
- - `cometchat-angular-troubleshooting` — SW registration debugging, ngsw issues
386
+ - `cometchat-angular-core` — init login order, `loggedInUser$`, environment config
387
+ - `cometchat-angular-production` — server-minted auth tokens (registration binds to the auth token)
388
+ - `cometchat-react-push` — sibling web-push concepts (self-hosted Web Push model; FCM + Notifications API here is the shared, recommended SDK path)
389
+ - `cometchat-angular-troubleshooting` — SW registration / FCM token debugging