@angular/fire 16.0.0-canary.e04cd7f → 16.0.0

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 (258) hide show
  1. package/README.md +200 -0
  2. package/analytics/analytics.module.d.ts +2 -2
  3. package/analytics/firebase.d.ts +4 -1
  4. package/analytics/screen-tracking.service.d.ts +3 -3
  5. package/app-check/app-check.d.ts +0 -6
  6. package/app-check/app-check.module.d.ts +3 -4
  7. package/app-check/firebase.d.ts +2 -1
  8. package/app-check/public_api.d.ts +2 -1
  9. package/auth/auth.module.d.ts +2 -2
  10. package/auth/firebase.d.ts +3 -1
  11. package/auth-guard/auth-guard.d.ts +2 -2
  12. package/compat/analytics/analytics.d.ts +1 -3
  13. package/compat/analytics/analytics.module.d.ts +1 -1
  14. package/compat/analytics/screen-tracking.service.d.ts +1 -1
  15. package/compat/analytics/user-tracking.service.d.ts +1 -1
  16. package/compat/auth/auth.d.ts +3 -3
  17. package/compat/auth-guard/auth-guard.d.ts +2 -2
  18. package/compat/database/database.d.ts +4 -4
  19. package/compat/database/interfaces.d.ts +2 -2
  20. package/compat/database/list/audit-trail.d.ts +1 -1
  21. package/compat/database/list/create-reference.d.ts +1 -1
  22. package/compat/database/list/data-operation.d.ts +1 -1
  23. package/compat/database/list/state-changes.d.ts +1 -1
  24. package/compat/database/object/create-reference.d.ts +1 -1
  25. package/compat/database/observable/fromRef.d.ts +1 -1
  26. package/compat/database/utils.d.ts +1 -1
  27. package/compat/firebase.app.module.d.ts +1 -1
  28. package/compat/firestore/collection/collection.d.ts +2 -2
  29. package/compat/firestore/collection-group/collection-group.d.ts +2 -2
  30. package/compat/firestore/document/document.d.ts +4 -4
  31. package/compat/firestore/firestore.d.ts +7 -7
  32. package/compat/firestore/interfaces.d.ts +2 -2
  33. package/compat/functions/functions.d.ts +3 -3
  34. package/compat/messaging/messaging.d.ts +2 -2
  35. package/compat/performance/performance.d.ts +2 -2
  36. package/compat/remote-config/remote-config.d.ts +15 -49
  37. package/compat/storage/observable/fromTask.d.ts +1 -2
  38. package/compat/storage/ref.d.ts +1 -1
  39. package/compat/storage/storage.d.ts +3 -3
  40. package/compat/storage/task.d.ts +1 -1
  41. package/core.d.ts +7 -0
  42. package/database/database.module.d.ts +2 -2
  43. package/docs/analytics.md +67 -0
  44. package/docs/app-check.md +53 -0
  45. package/docs/auth.md +165 -0
  46. package/docs/compat/analytics/getting-started.md +137 -0
  47. package/docs/compat/auth/getting-started.md +162 -0
  48. package/docs/compat/auth/router-guards.md +104 -0
  49. package/docs/compat/emulators/emulators.md +134 -0
  50. package/docs/compat/firestore/collections.md +326 -0
  51. package/docs/compat/firestore/documents.md +115 -0
  52. package/docs/compat/firestore/offline-data.md +39 -0
  53. package/docs/compat/firestore/querying-collections.md +204 -0
  54. package/docs/compat/functions/functions.md +166 -0
  55. package/docs/compat/messaging/messaging.md +232 -0
  56. package/docs/compat/performance/getting-started.md +132 -0
  57. package/docs/compat/remote-config/getting-started.md +134 -0
  58. package/docs/compat/rtdb/lists.md +257 -0
  59. package/docs/compat/rtdb/objects.md +182 -0
  60. package/docs/compat/rtdb/querying-lists.md +155 -0
  61. package/docs/compat/storage/storage.md +257 -0
  62. package/docs/compat.md +70 -0
  63. package/docs/database.md +175 -0
  64. package/docs/deploy/getting-started.md +204 -0
  65. package/docs/firebase.json +16 -0
  66. package/docs/firestore.md +148 -0
  67. package/docs/functions.md +52 -0
  68. package/docs/images/analytics-illo_1x.png +0 -0
  69. package/docs/images/auth-illo_1x.png +0 -0
  70. package/docs/images/cloud-messaging-illo_1x.png +0 -0
  71. package/docs/images/database-illo_1x.png +0 -0
  72. package/docs/images/firestore-illo_1x.png +0 -0
  73. package/docs/images/functions-illo_1x.png +0 -0
  74. package/docs/images/hosting-illo_1x.png +0 -0
  75. package/docs/images/performance-illo_1x.png +0 -0
  76. package/docs/images/reCAPTCHA-logo@1x.png +0 -0
  77. package/docs/images/remote-config-illo_1x.png +0 -0
  78. package/docs/images/storage-illo_1x.png +0 -0
  79. package/docs/install-and-setup.md +114 -0
  80. package/docs/install-angular-cli-windows10.md +82 -0
  81. package/docs/install-firebase-tools.md +78 -0
  82. package/docs/messaging.md +25 -0
  83. package/docs/performance.md +57 -0
  84. package/docs/remote-config.md +53 -0
  85. package/docs/storage.md +90 -0
  86. package/docs/universal/cloud-functions.md +96 -0
  87. package/docs/universal/getting-started.md +28 -0
  88. package/docs/universal/prerendering.md +72 -0
  89. package/docs/version-4-upgrade.md +119 -0
  90. package/docs/version-5-upgrade.md +82 -0
  91. package/docs/version-6-upgrade.md +16 -0
  92. package/docs/version-7-upgrade.md +298 -0
  93. package/esm2022/analytics/analytics.mjs +1 -1
  94. package/esm2022/analytics/analytics.module.mjs +10 -10
  95. package/esm2022/analytics/firebase.mjs +5 -2
  96. package/esm2022/analytics/screen-tracking.service.mjs +11 -10
  97. package/esm2022/analytics/user-tracking.service.mjs +5 -5
  98. package/esm2022/app/app.mjs +1 -1
  99. package/esm2022/app/app.module.mjs +9 -8
  100. package/esm2022/app-check/app-check.mjs +3 -9
  101. package/esm2022/app-check/app-check.module.mjs +12 -14
  102. package/esm2022/app-check/firebase.mjs +3 -2
  103. package/esm2022/app-check/public_api.mjs +3 -2
  104. package/esm2022/auth/auth.mjs +1 -1
  105. package/esm2022/auth/auth.module.mjs +11 -11
  106. package/esm2022/auth/firebase.mjs +4 -2
  107. package/esm2022/auth-guard/auth-guard.mjs +8 -6
  108. package/esm2022/auth-guard/auth-guard.module.mjs +7 -7
  109. package/esm2022/compat/analytics/analytics.mjs +12 -13
  110. package/esm2022/compat/analytics/analytics.module.mjs +14 -11
  111. package/esm2022/compat/analytics/screen-tracking.service.mjs +9 -9
  112. package/esm2022/compat/analytics/user-tracking.service.mjs +7 -7
  113. package/esm2022/compat/auth/auth.mjs +13 -13
  114. package/esm2022/compat/auth/auth.module.mjs +7 -7
  115. package/esm2022/compat/auth-guard/auth-guard.mjs +8 -6
  116. package/esm2022/compat/auth-guard/auth-guard.module.mjs +7 -7
  117. package/esm2022/compat/cache.mjs +2 -1
  118. package/esm2022/compat/database/database.mjs +10 -10
  119. package/esm2022/compat/database/database.module.mjs +7 -7
  120. package/esm2022/compat/database/interfaces.mjs +1 -1
  121. package/esm2022/compat/database/list/audit-trail.mjs +3 -3
  122. package/esm2022/compat/database/list/changes.mjs +5 -5
  123. package/esm2022/compat/database/list/create-reference.mjs +5 -5
  124. package/esm2022/compat/database/list/data-operation.mjs +1 -1
  125. package/esm2022/compat/database/list/snapshot-changes.mjs +1 -1
  126. package/esm2022/compat/database/list/state-changes.mjs +2 -2
  127. package/esm2022/compat/database/object/create-reference.mjs +2 -2
  128. package/esm2022/compat/database/object/snapshot-changes.mjs +1 -1
  129. package/esm2022/compat/database/observable/fromRef.mjs +3 -2
  130. package/esm2022/compat/database/utils.mjs +1 -1
  131. package/esm2022/compat/firebase.app.mjs +1 -1
  132. package/esm2022/compat/firebase.app.module.mjs +11 -9
  133. package/esm2022/compat/firestore/collection/changes.mjs +2 -2
  134. package/esm2022/compat/firestore/collection/collection.mjs +4 -4
  135. package/esm2022/compat/firestore/collection-group/collection-group.mjs +4 -4
  136. package/esm2022/compat/firestore/document/document.mjs +4 -4
  137. package/esm2022/compat/firestore/firestore.mjs +11 -11
  138. package/esm2022/compat/firestore/firestore.module.mjs +7 -7
  139. package/esm2022/compat/firestore/interfaces.mjs +1 -1
  140. package/esm2022/compat/firestore/observable/fromRef.mjs +2 -2
  141. package/esm2022/compat/functions/functions.mjs +8 -8
  142. package/esm2022/compat/functions/functions.module.mjs +7 -7
  143. package/esm2022/compat/messaging/messaging.mjs +13 -12
  144. package/esm2022/compat/messaging/messaging.module.mjs +7 -7
  145. package/esm2022/compat/performance/performance.mjs +14 -20
  146. package/esm2022/compat/performance/performance.module.mjs +8 -9
  147. package/esm2022/compat/performance/performance.service.mjs +5 -4
  148. package/esm2022/compat/proxy.mjs +6 -7
  149. package/esm2022/compat/remote-config/remote-config.mjs +10 -11
  150. package/esm2022/compat/remote-config/remote-config.module.mjs +7 -7
  151. package/esm2022/compat/storage/observable/fromTask.mjs +3 -1
  152. package/esm2022/compat/storage/pipes/storageUrl.pipe.mjs +9 -9
  153. package/esm2022/compat/storage/ref.mjs +3 -3
  154. package/esm2022/compat/storage/storage.mjs +8 -8
  155. package/esm2022/compat/storage/storage.module.mjs +7 -7
  156. package/esm2022/compat/storage/task.mjs +2 -2
  157. package/esm2022/core.mjs +7 -1
  158. package/esm2022/database/database.mjs +1 -1
  159. package/esm2022/database/database.module.mjs +11 -11
  160. package/esm2022/firestore/firebase.mjs +22 -2
  161. package/esm2022/firestore/firestore.mjs +1 -1
  162. package/esm2022/firestore/firestore.module.mjs +11 -11
  163. package/esm2022/firestore/lite/firebase.mjs +11 -2
  164. package/esm2022/firestore/lite/lite.mjs +1 -1
  165. package/esm2022/firestore/lite/lite.module.mjs +10 -11
  166. package/esm2022/firestore/lite/rxfire.mjs +4 -2
  167. package/esm2022/firestore/rxfire.mjs +4 -4
  168. package/esm2022/functions/functions.mjs +1 -1
  169. package/esm2022/functions/functions.module.mjs +11 -11
  170. package/esm2022/messaging/messaging.mjs +1 -1
  171. package/esm2022/messaging/messaging.module.mjs +9 -9
  172. package/esm2022/performance/performance.mjs +1 -1
  173. package/esm2022/performance/performance.module.mjs +12 -12
  174. package/esm2022/remote-config/is-remote-config-supported-factory.mjs +2 -2
  175. package/esm2022/remote-config/remote-config.mjs +1 -1
  176. package/esm2022/remote-config/remote-config.module.mjs +9 -9
  177. package/esm2022/storage/storage.mjs +1 -1
  178. package/esm2022/storage/storage.module.mjs +11 -11
  179. package/esm2022/zones.mjs +9 -11
  180. package/fesm2022/angular-fire-analytics.mjs +18 -14
  181. package/fesm2022/angular-fire-analytics.mjs.map +1 -1
  182. package/fesm2022/angular-fire-app-check.mjs +13 -19
  183. package/fesm2022/angular-fire-app-check.mjs.map +1 -1
  184. package/fesm2022/angular-fire-app.mjs +6 -5
  185. package/fesm2022/angular-fire-app.mjs.map +1 -1
  186. package/fesm2022/angular-fire-auth-guard.mjs +13 -11
  187. package/fesm2022/angular-fire-auth-guard.mjs.map +1 -1
  188. package/fesm2022/angular-fire-auth.mjs +10 -9
  189. package/fesm2022/angular-fire-auth.mjs.map +1 -1
  190. package/fesm2022/angular-fire-compat-analytics.mjs +29 -27
  191. package/fesm2022/angular-fire-compat-analytics.mjs.map +1 -1
  192. package/fesm2022/angular-fire-compat-auth-guard.mjs +12 -10
  193. package/fesm2022/angular-fire-compat-auth-guard.mjs.map +1 -1
  194. package/fesm2022/angular-fire-compat-auth.mjs +13 -13
  195. package/fesm2022/angular-fire-compat-auth.mjs.map +1 -1
  196. package/fesm2022/angular-fire-compat-database.mjs +129 -128
  197. package/fesm2022/angular-fire-compat-database.mjs.map +1 -1
  198. package/fesm2022/angular-fire-compat-firestore.mjs +96 -96
  199. package/fesm2022/angular-fire-compat-firestore.mjs.map +1 -1
  200. package/fesm2022/angular-fire-compat-functions.mjs +10 -10
  201. package/fesm2022/angular-fire-compat-functions.mjs.map +1 -1
  202. package/fesm2022/angular-fire-compat-messaging.mjs +13 -12
  203. package/fesm2022/angular-fire-compat-messaging.mjs.map +1 -1
  204. package/fesm2022/angular-fire-compat-performance.mjs +23 -29
  205. package/fesm2022/angular-fire-compat-performance.mjs.map +1 -1
  206. package/fesm2022/angular-fire-compat-remote-config.mjs +10 -11
  207. package/fesm2022/angular-fire-compat-remote-config.mjs.map +1 -1
  208. package/fesm2022/angular-fire-compat-storage.mjs +21 -19
  209. package/fesm2022/angular-fire-compat-storage.mjs.map +1 -1
  210. package/fesm2022/angular-fire-compat.mjs +15 -13
  211. package/fesm2022/angular-fire-compat.mjs.map +1 -1
  212. package/fesm2022/angular-fire-database.mjs +7 -8
  213. package/fesm2022/angular-fire-database.mjs.map +1 -1
  214. package/fesm2022/angular-fire-firestore-lite.mjs +21 -11
  215. package/fesm2022/angular-fire-firestore-lite.mjs.map +1 -1
  216. package/fesm2022/angular-fire-firestore.mjs +32 -13
  217. package/fesm2022/angular-fire-firestore.mjs.map +1 -1
  218. package/fesm2022/angular-fire-functions.mjs +8 -9
  219. package/fesm2022/angular-fire-functions.mjs.map +1 -1
  220. package/fesm2022/angular-fire-messaging.mjs +4 -4
  221. package/fesm2022/angular-fire-messaging.mjs.map +1 -1
  222. package/fesm2022/angular-fire-performance.mjs +7 -7
  223. package/fesm2022/angular-fire-performance.mjs.map +1 -1
  224. package/fesm2022/angular-fire-remote-config.mjs +4 -4
  225. package/fesm2022/angular-fire-remote-config.mjs.map +1 -1
  226. package/fesm2022/angular-fire-storage.mjs +6 -7
  227. package/fesm2022/angular-fire-storage.mjs.map +1 -1
  228. package/fesm2022/angular-fire.mjs +14 -10
  229. package/fesm2022/angular-fire.mjs.map +1 -1
  230. package/firestore/firebase.d.ts +21 -1
  231. package/firestore/firestore.module.d.ts +2 -2
  232. package/firestore/lite/firebase.d.ts +10 -1
  233. package/firestore/lite/lite.module.d.ts +2 -2
  234. package/firestore/lite/rxfire.d.ts +3 -1
  235. package/firestore/rxfire.d.ts +3 -3
  236. package/functions/functions.module.d.ts +2 -2
  237. package/messaging/messaging.module.d.ts +2 -2
  238. package/package.json +18 -18
  239. package/performance/performance.module.d.ts +2 -2
  240. package/remote-config/remote-config.module.d.ts +2 -2
  241. package/schematics/add/index.js +1 -1
  242. package/schematics/add/schema.json +16 -0
  243. package/schematics/builders.json +10 -0
  244. package/schematics/collection.json +15 -0
  245. package/schematics/common.js +1 -1
  246. package/schematics/deploy/actions.js +11 -11
  247. package/schematics/deploy/builder.js +2 -2
  248. package/schematics/deploy/schema.json +119 -0
  249. package/schematics/interfaces.js +9 -8
  250. package/schematics/migration.json +15 -0
  251. package/schematics/setup/index.js +33 -50
  252. package/schematics/setup/prompts.js +5 -6
  253. package/schematics/setup/schema.json +16 -0
  254. package/schematics/update/index.js +1 -1
  255. package/schematics/update/v7/index.js +2 -2
  256. package/schematics/utils.js +79 -63
  257. package/storage/storage.module.d.ts +2 -2
  258. package/publish.sh +0 -1
@@ -0,0 +1,166 @@
1
+ # AngularFireFunctions
2
+
3
+ > The Cloud Functions for Firebase client SDKs let you call functions directly from a Firebase app. To call a function from your app in this way, write and deploy an HTTPS Callable function in Cloud Functions, and then add client logic to call the function from your app.
4
+
5
+ > **NOTE**: [AngularFire has a new tree-shakable API](../../../README.md#developer-guide), you're looking at the documentation for the compatability version of the library. [See the v7 upgrade guide for more information on this change.](../../version-7-upgrade.md).
6
+
7
+ ### Import the `NgModule`
8
+
9
+ Cloud Functions for AngularFire is contained in the `@angular/fire/functions` module namespace. Import the `AngularFireFunctionsModule` in your `NgModule`. This sets up the `AngularFireFunction` service for dependency injection.
10
+
11
+ ```ts
12
+ import { BrowserModule } from '@angular/platform-browser';
13
+ import { NgModule } from '@angular/core';
14
+ import { AppComponent } from './app.component';
15
+ import { AngularFireModule } from '@angular/fire/compat';
16
+ import { AngularFireFunctionsModule } from '@angular/fire/compat/functions';
17
+ import { environment } from '../environments/environment';
18
+
19
+ @NgModule({
20
+ imports: [
21
+ BrowserModule,
22
+ AngularFireModule.initializeApp(environment.firebase),
23
+ AngularFireFunctionsModule
24
+ ],
25
+ declarations: [ AppComponent ],
26
+ bootstrap: [ AppComponent ]
27
+ })
28
+ export class AppModule {}
29
+ ```
30
+
31
+ ### Injecting the AngularFireFunctions service
32
+
33
+ Once the `AngularFireFunctionsModule` is registered you can inject the `AngularFireFunctions` service.
34
+
35
+ ```ts
36
+ import { Component } from '@angular/core';
37
+ import { AngularFireFunctions } from '@angular/fire/compat/functions';
38
+
39
+ @Component({
40
+ selector: 'app-component',
41
+ template: ``
42
+ })
43
+ export class AppComponent {
44
+ constructor(private fns: AngularFireFunctions) { }
45
+ }
46
+ ```
47
+
48
+ ### Creating a callable function
49
+
50
+ AngularFireFunctions is super easy. You create a function on the server side and then "call" it by its name with the client library.
51
+
52
+ | method | |
53
+ | ---------|--------------------|
54
+ | `httpCallable(name: string): (data: T) ` | Creates a callable function based on a function name. Returns a function that can create the observable of the http call. |
55
+ ```ts
56
+
57
+ import { Component } from '@angular/core';
58
+ import { AngularFireFunctions } from '@angular/fire/compat/functions';
59
+
60
+ @Component({
61
+ selector: 'app-root',
62
+ template: `{ data$ | async }`
63
+ })
64
+ export class AppComponent {
65
+ constructor(private fns: AngularFireFunctions) {
66
+ const callable = fns.httpsCallable('my-fn-name');
67
+ this.data$ = callable({ name: 'some-data' });
68
+ }
69
+ }
70
+ ```
71
+
72
+ Notice that calling `httpsCallable()` does not initiate the request. It creates a function, which when called creates an Observable, subscribe or convert it to a Promise to initiate the request.
73
+
74
+ ## Configuration via Dependency Injection
75
+
76
+ ### Functions Region
77
+
78
+ Allow configuration of the Function's region by adding `REGION` to the `providers` section of your `NgModule`. The default is `us-central1`.
79
+
80
+ ```ts
81
+ import { NgModule } from '@angular/core';
82
+ import { AngularFireFunctionsModule, REGION } from '@angular/fire/compat/functions';
83
+
84
+ @NgModule({
85
+ imports: [
86
+ ...
87
+ AngularFireFunctionsModule,
88
+ ...
89
+ ],
90
+ ...
91
+ providers: [
92
+ { provide: REGION, useValue: 'asia-northeast1' }
93
+ ]
94
+ })
95
+ export class AppModule {}
96
+
97
+ ```
98
+
99
+ ### Cloud Functions emulator
100
+
101
+ Point callable Functions to the Cloud Function emulator by adding `USE_EMULATOR` to the `providers` section of your `NgModule`.
102
+
103
+ ```ts
104
+ import { NgModule } from '@angular/core';
105
+ import { AngularFireFunctionsModule, USE_EMULATOR } from '@angular/fire/compat/functions';
106
+
107
+ @NgModule({
108
+ imports: [
109
+ ...
110
+ AngularFireFunctionsModule,
111
+ ...
112
+ ],
113
+ ...
114
+ providers: [
115
+ { provide: USE_EMULATOR, useValue: ['localhost', 5001] }
116
+ ]
117
+ })
118
+ export class AppModule {}
119
+
120
+ ```
121
+
122
+ [Learn more about integration with the Firebase Emulator suite on our dedicated guide here](../emulators/emulators.md).
123
+
124
+ ### Firebase Hosting integration
125
+
126
+ If you serve your app using [Firebase Hosting](https://firebase.google.com/docs/hosting/), you can configure Functions to be served from the same domain as your app. This will avoid an extra round-trip per function call due to [CORS preflight request](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request). This only applies to sites hosted via firebase on `us-central1`.
127
+
128
+ To set this up, you first need to update your `hosting` section in `firebase.json` and add one `rewrite` rule per function:
129
+
130
+ ```json
131
+ "hosting": {
132
+ "rewrites": [
133
+ {
134
+ "source": "/someFunction",
135
+ "function": "someFunction"
136
+ },
137
+ {
138
+ "source": "/anotherFunction",
139
+ "function": "anotherFunction"
140
+ },
141
+ ...
142
+ ]
143
+ }
144
+ ```
145
+
146
+ Deploy your hosting project to the new settings go into effect, finally configure functions origin to point at your app domain:
147
+
148
+ ```ts
149
+ import { NgModule } from '@angular/core';
150
+ import { AngularFireFunctionsModule, ORIGIN, NEW_ORIGIN_BEHAVIOR } from '@angular/fire/compat/functions';
151
+
152
+ @NgModule({
153
+ imports: [
154
+ ...
155
+ AngularFireFunctionsModule,
156
+ ...
157
+ ],
158
+ ...
159
+ providers: [
160
+ { provide: NEW_ORIGIN_BEHAVIOR, useValue: true },
161
+ { provide: ORIGIN, useValue: 'https://project-name.web.app' }
162
+ ]
163
+ })
164
+ export class AppModule {}
165
+
166
+ ```
@@ -0,0 +1,232 @@
1
+ # AngularFireMessaging
2
+
3
+ > The FCM JavaScript API lets you receive notification messages in web apps running in browsers that support the Push API.
4
+
5
+ > **NOTE**: [AngularFire has a new tree-shakable API](../../../README.md#developer-guide), you're looking at the documentation for the compatability version of the library. [See the v7 upgrade guide for more information on this change.](../../version-7-upgrade.md).
6
+
7
+ ### AngularFireMessaging is not out-of-the-box compatible with the Angular Service Worker
8
+
9
+ If you are using the Angular Service Worker, you are not currently able to use AngularFireMessaging out-of-the-box.
10
+ If you'd like this feature please add your 👍 to [this issue](https://github.com/angular/angular/issues/34352).
11
+
12
+ Your alternatives are to use
13
+ - [WorkboxJS](https://developers.google.com/web/tools/workbox/)
14
+ - Follow the discussion in [this issue](https://github.com/angular/angular/issues/34352) and [here](https://github.com/angular/angularfire/discussions/1923), manually registering the Angular Service Worker
15
+ - The Firebase Messaging Service Worker, which is detailed below
16
+
17
+ ### Import the `NgModule`
18
+
19
+ Push Notifications for AngularFire are contained in the `@angular/fire/messaging` module namespace. Import the `AngularFireMessagingModule` in your `NgModule`. This sets up the `AngularFireMessaging` service for dependency injection.
20
+
21
+ ```ts
22
+ import { BrowserModule } from '@angular/platform-browser';
23
+ import { NgModule } from '@angular/core';
24
+ import { AppComponent } from './app.component';
25
+ import { AngularFireModule } from '@angular/fire/compat';
26
+ import { AngularFireMessagingModule } from '@angular/fire/compat/messaging';
27
+ import { environment } from '../environments/environment';
28
+
29
+ @NgModule({
30
+ imports: [
31
+ BrowserModule,
32
+ AngularFireModule.initializeApp(environment.firebase),
33
+ AngularFireMessagingModule
34
+ ],
35
+ declarations: [ AppComponent ],
36
+ bootstrap: [ AppComponent ]
37
+ })
38
+ export class AppModule {}
39
+ ```
40
+
41
+ ### Setting up the Firebase Messaging Service Worker
42
+
43
+ There are two parts to Firebase Messaging, a Service Worker and the DOM API. AngularFireMessaging allows you to request permission, get tokens, delete tokens, and subscribe to messages on the DOM side. To register to receive notifications you need to set up the Service Worker. [The official Firebase documentation for setting up the details exactly how to do that](https://firebase.google.com/docs/cloud-messaging/js/client).
44
+
45
+ You can either use the `firebase-messaging-sw.js` file provided in the docs or you can set your own Service Worker to import that script. Make sure to set up your `angular.json` file to copy over the Service Worker file:
46
+
47
+ ```json
48
+ "assets": [
49
+ "assets",
50
+ "favicon.ico",
51
+ "firebase-messaging-sw.js",
52
+ "manifest.json"
53
+ ],
54
+ ```
55
+
56
+ [Warning] Remember update the `firebase-messaging-sw.js` everytime you update the `firebase` in package.json. The missmatch version could lead to unable to receive notification in `foreground`, you can create your `firebase-messaging-sw.js` like this:
57
+
58
+ ```js
59
+ // Give the service worker access to Firebase Messaging.
60
+ // Note that you can only use Firebase Messaging here, other Firebase libraries
61
+ // are not available in the service worker.
62
+ importScripts('https://www.gstatic.com/firebasejs/[the number of version matching with firebase in package.json]/firebase-app.js');
63
+ importScripts('https://www.gstatic.com/firebasejs/[for example: 7.16.1]/firebase-messaging.js');
64
+
65
+ // Initialize the Firebase app in the service worker by passing in the
66
+ // messagingSenderId.
67
+
68
+ firebase.initializeApp({
69
+ apiKey: '<your-key>',
70
+ authDomain: '<your-project-authdomain>',
71
+ databaseURL: '<your-database-URL>',
72
+ projectId: '<your-project-id>',
73
+ storageBucket: '<your-storage-bucket>',
74
+ messagingSenderId: '<your-messaging-sender-id>'
75
+ });
76
+
77
+ // Retrieve an instance of Firebase Messaging so that it can handle background
78
+ // messages.
79
+ const messaging = firebase.messaging();
80
+
81
+
82
+ ```
83
+
84
+ ### Requesting permission
85
+
86
+ Once you have the Firebase Messaging Service Worker set up and installed, you need to request permission to send a user notifications. While the browser will popup a UI for you, it is highly recommend to ask the user for permission with a custom UI and only ask when it makes sense. If you blindly ask for permission, you have an extremely high chance of getting denied or blocked.
87
+
88
+ ```ts
89
+ import { Component } from '@angular/core';
90
+ import { AngularFireMessaging } from '@angular/fire/compat/messaging';
91
+
92
+ @Component({
93
+ selector: 'app-root',
94
+ template: `
95
+ <button (click)="requestPermission()">
96
+ Hello this is a chat app. You should let us send you notifications for this reason.
97
+ </button>
98
+ `
99
+ })
100
+ export class AppComponent {
101
+ constructor(private afMessaging: AngularFireMessaging) { }
102
+ requestPermission() {
103
+ this.afMessaging.requestPermission
104
+ .subscribe(
105
+ () => { console.log('Permission granted!'); },
106
+ (error) => { console.error(error); },
107
+ );
108
+ }
109
+ }
110
+ ```
111
+
112
+ Once you have the permission of the user, you need their token. You can do this with the `getToken` observable or the `tokenChanges` observable. The `tokenChanges` observable listens for token refreshes whereas the `getToken` observable is a one-time call.
113
+
114
+ ```ts
115
+ import { Component } from '@angular/core';
116
+ import { AngularFireMessaging } from '@angular/fire/compat/messaging';
117
+ import { mergeMapTo } from 'rxjs/operators';
118
+
119
+ @Component({
120
+ selector: 'app-root',
121
+ template: `
122
+ <button (click)="requestPermission()">
123
+ Hello this is a chat app. You should let us send you notifications for this reason.
124
+ </button>
125
+ `
126
+ })
127
+ export class AppComponent {
128
+ constructor(private afMessaging: AngularFireMessaging) { }
129
+ requestPermission() {
130
+ this.afMessaging.requestPermission
131
+ .pipe(mergeMapTo(this.afMessaging.tokenChanges))
132
+ .subscribe(
133
+ (token) => { console.log('Permission granted! Save to the server!', token); },
134
+ (error) => { console.error(error); },
135
+ );
136
+ }
137
+ }
138
+ ```
139
+
140
+ Once you have a user's token, you need to save it to the server in order to send them notifications in response to events. Let's say you want to send a push each time a user sends a chat message. Once a user grants permission, you can send the token to the Realtime Database or Cloud Firestore and associate it with a unique id, like a Firebase Auth UID. You can then create a Cloud Function trigger that looks up the user's token when a chat message is created.
141
+
142
+ ### Shortcutting token requests
143
+
144
+ An easier way of requesting permission and getting tokens is with the `requestToken` observable. It combines the two steps above into one observable.
145
+
146
+ ```ts
147
+ import { Component } from '@angular/core';
148
+ import { AngularFireMessaging } from '@angular/fire/compat/messaging';
149
+
150
+ @Component({
151
+ selector: 'app-root',
152
+ template: `
153
+ <button (click)="requestPermission()">
154
+ Hello this is a chat app. You should let us send you notifications for this reason.
155
+ </button>
156
+ `
157
+ })
158
+ export class AppComponent {
159
+ constructor(private afMessaging: AngularFireMessaging) { }
160
+ requestPermission() {
161
+ this.afMessaging.requestToken
162
+ .subscribe(
163
+ (token) => { console.log('Permission granted! Save to the server!', token); },
164
+ (error) => { console.error(error); },
165
+ );
166
+ }
167
+ }
168
+ ```
169
+
170
+ The `requestToken` observable uses the `tokenChanges` observable to listen to refreshes.
171
+
172
+ ### Deleting tokens
173
+
174
+ Need to delete a user's token? Not a problem.
175
+
176
+ ```ts
177
+ import { Component } from '@angular/core';
178
+ import { AngularFireMessaging } from '@angular/fire/compat/messaging';
179
+ import { mergeMap } from 'rxjs/operators';
180
+
181
+ @Component({
182
+ selector: 'app-root',
183
+ template: `
184
+ <button (click)="deleteToken()">
185
+ Delete my token
186
+ </button>
187
+ `
188
+ })
189
+ export class AppComponent {
190
+ constructor(private afMessaging: AngularFireMessaging) { }
191
+ deleteToken() {
192
+ this.afMessaging.getToken
193
+ .pipe(mergeMap(token => this.afMessaging.deleteToken(token)))
194
+ .subscribe(
195
+ (token) => { console.log('Token deleted!'); },
196
+ );
197
+ }
198
+ }
199
+ ```
200
+
201
+ The code above requests the current user's token and passes it to the `deleteToken()` observable.
202
+
203
+ ### Subscribing to foreground messages
204
+
205
+ Once you have a user's token and they are subscribed, you can listen to messages in the foreground. The Firebase Messaging Service Worker handles background push notifications.
206
+
207
+ ```ts
208
+ import { Component } from '@angular/core';
209
+ import { AngularFireMessaging } from '@angular/fire/compat/messaging';
210
+
211
+ @Component({
212
+ selector: 'app-root',
213
+ template: `
214
+ <button (click)="listen()">
215
+ Get notified!
216
+ </button>
217
+ `
218
+ })
219
+ export class AppComponent {
220
+ constructor(private afMessaging: AngularFireMessaging) { }
221
+ listen() {
222
+ this.afMessaging.messages
223
+ .subscribe((message) => { console.log(message); });
224
+ }
225
+ }
226
+ ```
227
+
228
+ ### Sending notifications
229
+
230
+ [Sending a notification](https://firebase.google.com/docs/cloud-messaging/js/first-message) requires a call to a server. You can do this directly with an HTTP call or you can even build a Cloud Function to do this in response to an event. A Cloud Function trigger is ideal because you have trusted access to the database and can securely look up tokens to send to the right user. If you want to send push notifications via HTTP requests you'll need to secure the API call. This is usually done with a Firebase Auth UID. On the server you can verify the UID with the Firebase Admin SDK and allow access to get a user's push id.
231
+
232
+ The [Firebase Admin SDK has helper functions for sending notifications](https://firebase.google.com/docs/cloud-messaging/admin/send-messages) to the user and subscribing them to topics, which [simplifies sending grouped messages](https://firebase.google.com/docs/cloud-messaging/admin/manage-topic-subscriptions).
@@ -0,0 +1,132 @@
1
+ # Getting started with Performance Monitoring
2
+
3
+ > **NOTE**: [AngularFire has a new tree-shakable API](../../../README.md#developer-guide), you're looking at the documentation for the compatability version of the library. [See the v7 upgrade guide for more information on this change.](../../version-7-upgrade.md).
4
+
5
+ ## Automatic page load tracing
6
+
7
+ Understand your Angular application's real-world performance with [Firebase Performance Monitoring](https://firebase.google.com/docs/perf-mon). Performance Monitoring automatically provides a trace for **page load** when you add `AngularFirePerformanceModule` into your App Module's imports.
8
+
9
+ ```ts
10
+ import { AngularFireModule } from '@angular/fire/compat';
11
+ import { AngularFirePerformanceModule, PerformanceMonitoringService } from '@angular/fire/compat/performance';
12
+ import { environment } from '../environments/environment';
13
+
14
+ @NgModule({
15
+ imports: [
16
+ BrowserModule,
17
+ AngularFireModule.initializeApp(environment.firebase),
18
+ AngularFirePerformanceModule,
19
+ ...
20
+ ],
21
+ providers: [
22
+ PerformanceMonitoringService
23
+ ],
24
+ declarations: [ AppComponent ],
25
+ bootstrap: [ AppComponent ]
26
+ })
27
+ export class AppModule {}
28
+ ```
29
+
30
+ The page load trace breaks down into the following default metrics:
31
+
32
+ * [first paint traces](https://firebase.google.com/docs/perf-mon/automatic-web#first-paint) — measure the time between when the user navigates to a page and when any visual change happens
33
+ * [first contentful paint traces](https://firebase.google.com/docs/perf-mon/automatic-web#contentful-paint) — measure the time between when a user navigates to a page and when meaningful content displays, like an image or text
34
+ * [domInteractive traces](https://firebase.google.com/docs/perf-mon/automatic-web#domInteractive) — measure the time between when the user navigates to a page and when the page is considered interactive for the user
35
+ * [domContentLoadedEventEnd traces](https://firebase.google.com/docs/perf-mon/automatic-web#domContentLoaded) — measure the time between when the user navigates to a page and when the initial HTML document is completely loaded and parsed
36
+ * [loadEventEnd traces](https://firebase.google.com/docs/perf-mon/automatic-web#loadEventEnd) — measure the time between when the user navigates to the page and when the current document's load event completes
37
+ * [first input delay traces](https://firebase.google.com/docs/perf-mon/automatic-web#input-delay) — measure the time between when the user interacts with a page and when the browser is able to respond to that input
38
+ * **Angular specific traces** - `PerformanceMonitoringService` will measure the time needed for `ApplicationRef.isStable` to be true, an important metric to track if you're concerned about solving Zone.js issues for proper functionality of NGSW and Server Side Rendering
39
+
40
+ ### Measuring First Input Delay
41
+
42
+ > First Input Delay (FID) measures the time from when a user first interacts with your site (i.e. when they click a link, tap on a button, or use a custom, JavaScript-powered control) to the time when the browser is actually able to respond to that interaction. [See the article on the Google Developer's Blog for more information on FID.](https://developers.google.com/web/updates/2018/05/first-input-delay)
43
+
44
+ In order to track first input delay, you'll want to [polyfill the browser performance API](https://github.com/GoogleChromeLabs/first-input-delay):
45
+
46
+ `npm install --save-dev first-input-delay`
47
+
48
+ Then add `import 'first-input-delay';` to your `src/polyfills.ts`.
49
+
50
+ ## Manual traces
51
+
52
+ You can inject `AngularFirePerformance` to perform manual traces.
53
+
54
+ ```ts
55
+ constructor(private performance: AngularFirePerformance) {}
56
+
57
+ ...
58
+
59
+ const trace = await this.performance.trace('some-trace');
60
+ trace.start();
61
+ ...
62
+ trace.stop();
63
+ ```
64
+
65
+ ## RXJS operators
66
+
67
+ AngularFire provides a number of RXJS operators which wrap the User Timing API. These are picked up by performance monitoring tools such as Chrome Inspector and Firebase Performance Monitoring.
68
+
69
+ ```ts
70
+ import { trace } from '@angular/fire/compat/performance';
71
+
72
+ ...
73
+
74
+ constructor(private performance: AngularFirePerformance, private afs: AngularFirestore) {}
75
+
76
+ ngOnInit() {
77
+ this.articles = afs.collection('articles')
78
+ .collection('articles', ref => ref.orderBy('publishedAt', 'desc'))
79
+ .snapshotChanges()
80
+ .pipe(
81
+ // measure the amount of time between the Observable being subscribed to and first emission (or completion)
82
+ trace('getArticles'),
83
+ map(articles => ...)
84
+ );
85
+ }
86
+ ```
87
+
88
+ ### `trace(name: string)`
89
+
90
+ The most basic operator, `trace` will measure the amount of time it takes for your observable to either complete or emit its first value. Beyond the basic trace there are several other operators:
91
+
92
+ <h3>
93
+ <pre>
94
+ traceUntil(
95
+ name: string,
96
+ test: (T) => Boolean,
97
+ options?: { orComplete?: true }
98
+ )
99
+ </pre>
100
+ </h3>
101
+
102
+ Trace the observable until the first emission that passes the provided test.
103
+
104
+ If the `orComplete` option is passed it will complete the trace when the observable completes, even if an emission never passed the provided test.
105
+
106
+ <h3>
107
+ <pre>
108
+ traceWhile(
109
+ name: string,
110
+ test: (T) => Boolean,
111
+ options?: { orComplete?: true }
112
+ )
113
+ </pre>
114
+ </h3>
115
+
116
+ Starting with an emission that passes the provided test, trace until an emission fails the test.
117
+
118
+ If the `orComplete` option is passed it will complete any existing trace when the observable completes.
119
+
120
+ ### `traceUntilLast(name: string)`
121
+
122
+ Trace the observable until completion.
123
+
124
+ ### `traceUntilFirst(name: string)`
125
+
126
+ Traces the observable until the first emission.
127
+
128
+ ## Advanced usage
129
+
130
+ ### Configuration via Dependency Injection
131
+
132
+ Set `INSTRUMENTATION_ENABLED` or `DATA_COLLECTION_ENABLED` to false disable all automatic and custom traces respectively.
@@ -0,0 +1,134 @@
1
+ <h1>Getting started with Remote Config <em><abbr title="beta">β<abbr></em></h1>
2
+
3
+ `AngularFireRemoteConfig` dynamically imports the `firebase/remote-config` library on demand, provides convenience observables, pipes, and a promisified version of the [Firebase Remote Config SDK (`firebase.remoteConfig.RemoteConfig`)](https://firebase.google.com/docs/reference/js/firebase.remoteconfig.RemoteConfig).
4
+
5
+ > **NOTE**: [AngularFire has a new tree-shakable API](../../../README.md#developer-guide), you're looking at the documentation for the compatability version of the library. [See the v7 upgrade guide for more information on this change.](../../version-7-upgrade.md).
6
+
7
+ ### API:
8
+
9
+ ```ts
10
+ class AngularFireRemoteConfigModule { }
11
+
12
+ interface ConfigTemplate {[key:string]: string|number|boolean}
13
+
14
+ type Parameter extends remoteConfig.Value {
15
+ key: string,
16
+ fetchTimeMillis: number
17
+ }
18
+
19
+ class AngularFireRemoteConfig {
20
+ changes: Observable<Parameter>;
21
+ parameters: Observable<Parameter[]>;
22
+ numbers: Observable<{[key:string]: number|undefined}> & {[key:string]: Observable<number>};
23
+ booleans: Observable<{[key:string]: boolean|undefined}> & {[key:string]: Observable<boolean>};
24
+ strings: Observable<{[key:string]: string|undefined}> & {[key:string]: Observable<string|undefined>};
25
+
26
+ // from firebase.remoteConfig() proxy:
27
+ activate: () => Promise<boolean>;
28
+ ensureInitialized: () => Promise<void>;
29
+ fetch: () => Promise<void>;
30
+ fetchAndActivate: () => Promise<boolean>;
31
+ getAll: () => Promise<{[key:string]: remoteConfig.Value}>;
32
+ getBoolean: (key:string) => Promise<boolean>;
33
+ getNumber: (key:string) => Promise<number>;
34
+ getString: (key:string) => Promise<string>;
35
+ getValue: (key:string) => Promise<remoteConfig.Value>;
36
+ setLogLevel: (logLevel: remoteConfig.LogLevel) => Promise<void>;
37
+ settings: Promise<remoteConfig.Settings>;
38
+ defaultConfig: Promise<{[key: string]: string | number | boolean}>;
39
+ fetchTimeMillis: Promise<number>;
40
+ lastFetchStatus: Promise<remoteConfig.FetchStatus>;
41
+ }
42
+
43
+ // Pipes for working with .changes and .parameters
44
+ filterRemote: () => MonoTypeOperatorFunction<Parameter | Parameter[]>
45
+ filterFresh: (interval: number) => MonoTypeOperatorFunction<Parameter | Parameter[]>
46
+ budget: <T>(interval: number) => MonoTypeOperatorFunction<T>
47
+
48
+ // scanToObject is for use with .changes
49
+ scanToObject: () => OperatorFunction<Parameter, {[key: string]: string|undefined}>
50
+
51
+ // mapToObject is the same behavior as scanToObject but for use with .parameters
52
+ mapToObject: () => OperatorFunction<Parameter[], {[key: string]: string|undefined}>
53
+
54
+ SETTINGS = InjectionToken<remoteConfig.Settings>;
55
+ DEFAULTS = InjectionToken<ConfigTemplate>;
56
+ ```
57
+
58
+ ## Configuration with Dependency Injection
59
+
60
+ ### Configure Remote Config with `SETTINGS`
61
+
62
+ Using the `SETTINGS` DI Token (*default: {}*) will allow you to [configure Firebase Remote Config](https://firebase.google.com/docs/reference/js/firebase.remoteconfig.Settings.html).
63
+
64
+ ### Configure default values with `DEFAULTS`
65
+
66
+ Providing `DEFAULTS ({[key: string]: string | number | boolean})` tells `AngularFireRemoteConfig` to emit the provided defaults first. This allows you to count on Remote Config when the user is offline or in environments that the Remote Config service does not handle (i.e. Server Side Rendering).
67
+
68
+ ## Putting it all together
69
+
70
+ ```ts
71
+ import { AngularFireRemoteConfigModule, DEFAULTS, SETTINGS } from '@angular/fire/compat/remote-config';
72
+
73
+ @NgModule({
74
+ imports: [
75
+ AngularFireModule.initializeApp(environment.firebase),
76
+ AngularFireRemoteConfigModule
77
+ ],
78
+ providers: [
79
+ { provide: DEFAULTS, useValue: { enableAwesome: true } },
80
+ {
81
+ provide: SETTINGS,
82
+ useFactory: () => isDevMode() ? { minimumFetchIntervalMillis: 10_000 } : {}
83
+ }
84
+ ]
85
+ })
86
+ export class AppModule { }
87
+
88
+ ...
89
+
90
+ constructor(remoteConfig: AngularFireRemoteConfig) {
91
+ remoteConfig.changes.pipe(
92
+ filterFresh(172_800_000), // ensure we have values from at least 48 hours ago
93
+ first(),
94
+ // scanToObject when used this way is similar to defaults
95
+ // but most importantly smart-casts remote config values and adds type safety
96
+ scanToObject({
97
+ enableAwesome: true,
98
+ titleBackgroundColor: 'blue',
99
+ titleFontSize: 12
100
+ })
101
+ ).subscribe(…);
102
+
103
+ // all remote config values cast as strings
104
+ remoteConfig.strings.subscribe(...)
105
+ remoteConfig.booleans.subscribe(...); // as booleans
106
+ remoteConfig.numbers.subscribe(...); // as numbers
107
+
108
+ // convenience for observing a single string
109
+ remoteConfig.strings.titleBackgroundColor.subscribe(...);
110
+ remoteConfig.booleans.enableAwesome.subscribe(...); // boolean
111
+ remoteConfig.numbers.titleBackgroundColor.subscribe(...); // number
112
+
113
+ // however those may emit more than once as the remote config cache fires and gets fresh values
114
+ // from the server. You can filter it out of .changes for more control:
115
+ remoteConfig.changes.pipe(
116
+ filter(param => param.key === 'titleBackgroundColor'),
117
+ map(param => param.asString())
118
+ // budget at most 800ms and return the freshest value possible in that time
119
+ // our budget pipe is similar to timeout but won't error or abort the pending server fetch
120
+ // (it won't emit it, if the deadline is exceeded, but it will have been fetched so can use the
121
+ // freshest values on next subscription)
122
+ budget(800),
123
+ last()
124
+ ).subscribe(...)
125
+
126
+ // just like .changes, but scanned into an array
127
+ remoteConfig.parameters.subscribe(all => ...);
128
+
129
+ // or make promisified firebase().remoteConfig() calls direct off AngularFireRemoteConfig
130
+ // using our proxy
131
+ remoteConfig.getAll().then(all => ...);
132
+ remoteConfig.lastFetchStatus.then(status => ...);
133
+ }
134
+ ```