@angular/fire 16.0.0-canary.596e208 → 16.0.0-canary.78407bc

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 (253) 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.module.d.ts +3 -3
  6. package/app-check/firebase.d.ts +2 -1
  7. package/auth/auth.module.d.ts +2 -2
  8. package/auth/firebase.d.ts +3 -1
  9. package/auth-guard/auth-guard.d.ts +2 -2
  10. package/compat/analytics/analytics.d.ts +1 -3
  11. package/compat/analytics/analytics.module.d.ts +1 -1
  12. package/compat/analytics/screen-tracking.service.d.ts +1 -1
  13. package/compat/analytics/user-tracking.service.d.ts +1 -1
  14. package/compat/auth/auth.d.ts +3 -3
  15. package/compat/auth-guard/auth-guard.d.ts +2 -2
  16. package/compat/database/database.d.ts +4 -4
  17. package/compat/database/interfaces.d.ts +2 -2
  18. package/compat/database/list/audit-trail.d.ts +1 -1
  19. package/compat/database/list/create-reference.d.ts +1 -1
  20. package/compat/database/list/data-operation.d.ts +1 -1
  21. package/compat/database/list/state-changes.d.ts +1 -1
  22. package/compat/database/object/create-reference.d.ts +1 -1
  23. package/compat/database/observable/fromRef.d.ts +1 -1
  24. package/compat/database/utils.d.ts +1 -1
  25. package/compat/firebase.app.module.d.ts +1 -1
  26. package/compat/firestore/collection/collection.d.ts +2 -2
  27. package/compat/firestore/collection-group/collection-group.d.ts +2 -2
  28. package/compat/firestore/document/document.d.ts +4 -4
  29. package/compat/firestore/firestore.d.ts +7 -7
  30. package/compat/firestore/interfaces.d.ts +2 -2
  31. package/compat/functions/functions.d.ts +3 -3
  32. package/compat/messaging/messaging.d.ts +2 -2
  33. package/compat/performance/performance.d.ts +2 -2
  34. package/compat/remote-config/remote-config.d.ts +15 -49
  35. package/compat/storage/observable/fromTask.d.ts +1 -2
  36. package/compat/storage/ref.d.ts +1 -1
  37. package/compat/storage/storage.d.ts +3 -3
  38. package/compat/storage/task.d.ts +1 -1
  39. package/database/database.module.d.ts +2 -2
  40. package/docs/analytics.md +67 -0
  41. package/docs/app-check.md +53 -0
  42. package/docs/auth.md +165 -0
  43. package/docs/compat/analytics/getting-started.md +137 -0
  44. package/docs/compat/auth/getting-started.md +162 -0
  45. package/docs/compat/auth/router-guards.md +104 -0
  46. package/docs/compat/emulators/emulators.md +134 -0
  47. package/docs/compat/firestore/collections.md +326 -0
  48. package/docs/compat/firestore/documents.md +115 -0
  49. package/docs/compat/firestore/offline-data.md +39 -0
  50. package/docs/compat/firestore/querying-collections.md +204 -0
  51. package/docs/compat/functions/functions.md +166 -0
  52. package/docs/compat/messaging/messaging.md +232 -0
  53. package/docs/compat/performance/getting-started.md +132 -0
  54. package/docs/compat/remote-config/getting-started.md +134 -0
  55. package/docs/compat/rtdb/lists.md +257 -0
  56. package/docs/compat/rtdb/objects.md +182 -0
  57. package/docs/compat/rtdb/querying-lists.md +155 -0
  58. package/docs/compat/storage/storage.md +257 -0
  59. package/docs/compat.md +70 -0
  60. package/docs/database.md +175 -0
  61. package/docs/deploy/getting-started.md +204 -0
  62. package/docs/firebase.json +16 -0
  63. package/docs/firestore.md +148 -0
  64. package/docs/functions.md +52 -0
  65. package/docs/images/analytics-illo_1x.png +0 -0
  66. package/docs/images/auth-illo_1x.png +0 -0
  67. package/docs/images/cloud-messaging-illo_1x.png +0 -0
  68. package/docs/images/database-illo_1x.png +0 -0
  69. package/docs/images/firestore-illo_1x.png +0 -0
  70. package/docs/images/functions-illo_1x.png +0 -0
  71. package/docs/images/hosting-illo_1x.png +0 -0
  72. package/docs/images/performance-illo_1x.png +0 -0
  73. package/docs/images/reCAPTCHA-logo@1x.png +0 -0
  74. package/docs/images/remote-config-illo_1x.png +0 -0
  75. package/docs/images/storage-illo_1x.png +0 -0
  76. package/docs/install-and-setup.md +114 -0
  77. package/docs/install-angular-cli-windows10.md +82 -0
  78. package/docs/install-firebase-tools.md +78 -0
  79. package/docs/messaging.md +25 -0
  80. package/docs/performance.md +57 -0
  81. package/docs/remote-config.md +53 -0
  82. package/docs/storage.md +90 -0
  83. package/docs/universal/cloud-functions.md +96 -0
  84. package/docs/universal/getting-started.md +28 -0
  85. package/docs/universal/prerendering.md +72 -0
  86. package/docs/version-4-upgrade.md +119 -0
  87. package/docs/version-5-upgrade.md +82 -0
  88. package/docs/version-6-upgrade.md +16 -0
  89. package/docs/version-7-upgrade.md +298 -0
  90. package/esm2022/analytics/analytics.mjs +1 -1
  91. package/esm2022/analytics/analytics.module.mjs +10 -10
  92. package/esm2022/analytics/firebase.mjs +5 -2
  93. package/esm2022/analytics/screen-tracking.service.mjs +11 -10
  94. package/esm2022/analytics/user-tracking.service.mjs +5 -5
  95. package/esm2022/app/app.mjs +1 -1
  96. package/esm2022/app/app.module.mjs +9 -8
  97. package/esm2022/app-check/app-check.mjs +2 -2
  98. package/esm2022/app-check/app-check.module.mjs +10 -11
  99. package/esm2022/app-check/firebase.mjs +3 -2
  100. package/esm2022/auth/auth.mjs +1 -1
  101. package/esm2022/auth/auth.module.mjs +10 -10
  102. package/esm2022/auth/firebase.mjs +4 -2
  103. package/esm2022/auth-guard/auth-guard.mjs +8 -6
  104. package/esm2022/auth-guard/auth-guard.module.mjs +7 -7
  105. package/esm2022/compat/analytics/analytics.mjs +12 -13
  106. package/esm2022/compat/analytics/analytics.module.mjs +14 -11
  107. package/esm2022/compat/analytics/screen-tracking.service.mjs +9 -9
  108. package/esm2022/compat/analytics/user-tracking.service.mjs +7 -7
  109. package/esm2022/compat/auth/auth.mjs +13 -13
  110. package/esm2022/compat/auth/auth.module.mjs +7 -7
  111. package/esm2022/compat/auth-guard/auth-guard.mjs +8 -6
  112. package/esm2022/compat/auth-guard/auth-guard.module.mjs +7 -7
  113. package/esm2022/compat/cache.mjs +2 -1
  114. package/esm2022/compat/database/database.mjs +10 -10
  115. package/esm2022/compat/database/database.module.mjs +7 -7
  116. package/esm2022/compat/database/interfaces.mjs +1 -1
  117. package/esm2022/compat/database/list/audit-trail.mjs +3 -3
  118. package/esm2022/compat/database/list/changes.mjs +5 -5
  119. package/esm2022/compat/database/list/create-reference.mjs +5 -5
  120. package/esm2022/compat/database/list/data-operation.mjs +1 -1
  121. package/esm2022/compat/database/list/snapshot-changes.mjs +1 -1
  122. package/esm2022/compat/database/list/state-changes.mjs +2 -2
  123. package/esm2022/compat/database/object/create-reference.mjs +2 -2
  124. package/esm2022/compat/database/object/snapshot-changes.mjs +1 -1
  125. package/esm2022/compat/database/observable/fromRef.mjs +3 -2
  126. package/esm2022/compat/database/utils.mjs +1 -1
  127. package/esm2022/compat/firebase.app.mjs +1 -1
  128. package/esm2022/compat/firebase.app.module.mjs +11 -9
  129. package/esm2022/compat/firestore/collection/changes.mjs +2 -2
  130. package/esm2022/compat/firestore/collection/collection.mjs +4 -4
  131. package/esm2022/compat/firestore/collection-group/collection-group.mjs +4 -4
  132. package/esm2022/compat/firestore/document/document.mjs +4 -4
  133. package/esm2022/compat/firestore/firestore.mjs +11 -11
  134. package/esm2022/compat/firestore/firestore.module.mjs +7 -7
  135. package/esm2022/compat/firestore/interfaces.mjs +1 -1
  136. package/esm2022/compat/firestore/observable/fromRef.mjs +2 -2
  137. package/esm2022/compat/functions/functions.mjs +8 -8
  138. package/esm2022/compat/functions/functions.module.mjs +7 -7
  139. package/esm2022/compat/messaging/messaging.mjs +13 -12
  140. package/esm2022/compat/messaging/messaging.module.mjs +7 -7
  141. package/esm2022/compat/performance/performance.mjs +14 -20
  142. package/esm2022/compat/performance/performance.module.mjs +8 -9
  143. package/esm2022/compat/performance/performance.service.mjs +5 -4
  144. package/esm2022/compat/proxy.mjs +6 -7
  145. package/esm2022/compat/remote-config/remote-config.mjs +10 -11
  146. package/esm2022/compat/remote-config/remote-config.module.mjs +7 -7
  147. package/esm2022/compat/storage/observable/fromTask.mjs +3 -1
  148. package/esm2022/compat/storage/pipes/storageUrl.pipe.mjs +9 -9
  149. package/esm2022/compat/storage/ref.mjs +3 -3
  150. package/esm2022/compat/storage/storage.mjs +8 -8
  151. package/esm2022/compat/storage/storage.module.mjs +7 -7
  152. package/esm2022/compat/storage/task.mjs +2 -2
  153. package/esm2022/core.mjs +1 -3
  154. package/esm2022/database/database.mjs +1 -1
  155. package/esm2022/database/database.module.mjs +10 -10
  156. package/esm2022/firestore/firebase.mjs +22 -2
  157. package/esm2022/firestore/firestore.mjs +1 -1
  158. package/esm2022/firestore/firestore.module.mjs +10 -10
  159. package/esm2022/firestore/lite/firebase.mjs +11 -2
  160. package/esm2022/firestore/lite/lite.mjs +1 -1
  161. package/esm2022/firestore/lite/lite.module.mjs +9 -9
  162. package/esm2022/firestore/lite/rxfire.mjs +4 -2
  163. package/esm2022/firestore/rxfire.mjs +4 -4
  164. package/esm2022/functions/functions.mjs +1 -1
  165. package/esm2022/functions/functions.module.mjs +10 -10
  166. package/esm2022/messaging/messaging.mjs +1 -1
  167. package/esm2022/messaging/messaging.module.mjs +9 -9
  168. package/esm2022/performance/performance.mjs +1 -1
  169. package/esm2022/performance/performance.module.mjs +12 -12
  170. package/esm2022/remote-config/is-remote-config-supported-factory.mjs +2 -2
  171. package/esm2022/remote-config/remote-config.mjs +1 -1
  172. package/esm2022/remote-config/remote-config.module.mjs +9 -9
  173. package/esm2022/storage/storage.mjs +1 -1
  174. package/esm2022/storage/storage.module.mjs +10 -10
  175. package/esm2022/zones.mjs +9 -11
  176. package/fesm2022/angular-fire-analytics.mjs +18 -14
  177. package/fesm2022/angular-fire-analytics.mjs.map +1 -1
  178. package/fesm2022/angular-fire-app-check.mjs +8 -8
  179. package/fesm2022/angular-fire-app-check.mjs.map +1 -1
  180. package/fesm2022/angular-fire-app.mjs +6 -5
  181. package/fesm2022/angular-fire-app.mjs.map +1 -1
  182. package/fesm2022/angular-fire-auth-guard.mjs +13 -11
  183. package/fesm2022/angular-fire-auth-guard.mjs.map +1 -1
  184. package/fesm2022/angular-fire-auth.mjs +8 -6
  185. package/fesm2022/angular-fire-auth.mjs.map +1 -1
  186. package/fesm2022/angular-fire-compat-analytics.mjs +29 -27
  187. package/fesm2022/angular-fire-compat-analytics.mjs.map +1 -1
  188. package/fesm2022/angular-fire-compat-auth-guard.mjs +12 -10
  189. package/fesm2022/angular-fire-compat-auth-guard.mjs.map +1 -1
  190. package/fesm2022/angular-fire-compat-auth.mjs +13 -13
  191. package/fesm2022/angular-fire-compat-auth.mjs.map +1 -1
  192. package/fesm2022/angular-fire-compat-database.mjs +129 -128
  193. package/fesm2022/angular-fire-compat-database.mjs.map +1 -1
  194. package/fesm2022/angular-fire-compat-firestore.mjs +96 -96
  195. package/fesm2022/angular-fire-compat-firestore.mjs.map +1 -1
  196. package/fesm2022/angular-fire-compat-functions.mjs +10 -10
  197. package/fesm2022/angular-fire-compat-functions.mjs.map +1 -1
  198. package/fesm2022/angular-fire-compat-messaging.mjs +13 -12
  199. package/fesm2022/angular-fire-compat-messaging.mjs.map +1 -1
  200. package/fesm2022/angular-fire-compat-performance.mjs +23 -29
  201. package/fesm2022/angular-fire-compat-performance.mjs.map +1 -1
  202. package/fesm2022/angular-fire-compat-remote-config.mjs +10 -11
  203. package/fesm2022/angular-fire-compat-remote-config.mjs.map +1 -1
  204. package/fesm2022/angular-fire-compat-storage.mjs +21 -19
  205. package/fesm2022/angular-fire-compat-storage.mjs.map +1 -1
  206. package/fesm2022/angular-fire-compat.mjs +15 -13
  207. package/fesm2022/angular-fire-compat.mjs.map +1 -1
  208. package/fesm2022/angular-fire-database.mjs +5 -5
  209. package/fesm2022/angular-fire-database.mjs.map +1 -1
  210. package/fesm2022/angular-fire-firestore-lite.mjs +19 -8
  211. package/fesm2022/angular-fire-firestore-lite.mjs.map +1 -1
  212. package/fesm2022/angular-fire-firestore.mjs +30 -10
  213. package/fesm2022/angular-fire-firestore.mjs.map +1 -1
  214. package/fesm2022/angular-fire-functions.mjs +6 -6
  215. package/fesm2022/angular-fire-functions.mjs.map +1 -1
  216. package/fesm2022/angular-fire-messaging.mjs +4 -4
  217. package/fesm2022/angular-fire-messaging.mjs.map +1 -1
  218. package/fesm2022/angular-fire-performance.mjs +7 -7
  219. package/fesm2022/angular-fire-performance.mjs.map +1 -1
  220. package/fesm2022/angular-fire-remote-config.mjs +4 -4
  221. package/fesm2022/angular-fire-remote-config.mjs.map +1 -1
  222. package/fesm2022/angular-fire-storage.mjs +4 -4
  223. package/fesm2022/angular-fire-storage.mjs.map +1 -1
  224. package/fesm2022/angular-fire.mjs +7 -11
  225. package/fesm2022/angular-fire.mjs.map +1 -1
  226. package/firestore/firebase.d.ts +21 -1
  227. package/firestore/firestore.module.d.ts +2 -2
  228. package/firestore/lite/firebase.d.ts +10 -1
  229. package/firestore/lite/lite.module.d.ts +2 -2
  230. package/firestore/lite/rxfire.d.ts +3 -1
  231. package/firestore/rxfire.d.ts +3 -3
  232. package/functions/functions.module.d.ts +2 -2
  233. package/messaging/messaging.module.d.ts +2 -2
  234. package/package.json +12 -12
  235. package/performance/performance.module.d.ts +2 -2
  236. package/remote-config/remote-config.module.d.ts +2 -2
  237. package/schematics/add/index.js +1 -1
  238. package/schematics/add/schema.json +16 -0
  239. package/schematics/builders.json +10 -0
  240. package/schematics/collection.json +15 -0
  241. package/schematics/common.js +1 -1
  242. package/schematics/deploy/actions.js +11 -11
  243. package/schematics/deploy/builder.js +2 -2
  244. package/schematics/deploy/schema.json +119 -0
  245. package/schematics/migration.json +15 -0
  246. package/schematics/setup/index.js +5 -6
  247. package/schematics/setup/prompts.js +5 -6
  248. package/schematics/setup/schema.json +16 -0
  249. package/schematics/update/index.js +1 -1
  250. package/schematics/update/v7/index.js +2 -2
  251. package/schematics/utils.js +4 -4
  252. package/storage/storage.module.d.ts +2 -2
  253. package/publish.sh +0 -1
@@ -0,0 +1,257 @@
1
+ # 3. Retrieving data as lists
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
+ > AngularFire synchronizes data as lists using the `AngularFireList` service.
6
+
7
+ The `AngularFireList` service is not created by itself, but through the `AngularFireDatabase` service.
8
+
9
+ The guide below demonstrates how to retrieve, save, and remove data as lists.
10
+
11
+ ## Injecting the `AngularFireDatabase` service
12
+
13
+ **Make sure you have bootstrapped your application for AngularFire. See the Installation guide for bootstrap setup.**
14
+
15
+ AngularFireDatabase is a service which can be injected through the constructor of your Angular component or `@Injectable()` service.
16
+ In the previous step, we modified the `/src/app/app.component.ts` to retrieve data as an object. In this step, let's start with a clean slate.
17
+
18
+ Replace your `/src/app/app.component.ts` from previous step to look like below.
19
+
20
+ ```ts
21
+ import { Component } from '@angular/core';
22
+ import { AngularFireDatabase } from '@angular/fire/compat/database';
23
+
24
+ @Component({
25
+ selector: 'app-root',
26
+ templateUrl: 'app.component.html',
27
+ styleUrls: ['app.component.css']
28
+ })
29
+ export class AppComponent {
30
+ constructor(db: AngularFireDatabase) { }
31
+ }
32
+ ```
33
+
34
+ In this section, we're going to modify the `/src/app/app.component.ts` to retrieve data as list, but before that let's look at ways around how to bind to a list.
35
+
36
+ ## Create a list binding
37
+
38
+ Data is retrieved through the `AngularFireDatabase` service. The service is also generic. Provide the singular type and not the array type.
39
+
40
+ ```ts
41
+ const listRef = db.list('items');
42
+ const shirtsRef = db.list<Shirt>('shirts');
43
+ ```
44
+
45
+ ### Retrieve data
46
+
47
+ To get the list in realtime, create a list binding as a property of your component or service.
48
+
49
+ Then in your template, you can use the `async` pipe to unwrap the binding.
50
+
51
+ Update `/src/app/app.component.ts` to import `AngularFireList` from `@angular/fire` and iterate through the list once data is retrieved. Also note the change in attribute `templateUrl` to inline `template` below.
52
+
53
+ ```ts
54
+ import { Component } from '@angular/core';
55
+ import { AngularFireDatabase } from '@angular/fire/compat/database';
56
+ import { Observable } from 'rxjs';
57
+
58
+ @Component({
59
+ selector: 'app-root',
60
+ template: `
61
+ <ul>
62
+ <li *ngFor="let item of items | async">
63
+ {{ item | json }}
64
+ </li>
65
+ </ul>
66
+ `,
67
+ })
68
+ export class AppComponent {
69
+ items: Observable<any[]>;
70
+ constructor(db: AngularFireDatabase) {
71
+ this.items = db.list('items').valueChanges();
72
+ }
73
+ }
74
+ ```
75
+
76
+ ## `AngularFireAction` - Action based API
77
+
78
+ AngularFire provides methods that stream data back as redux compatible actions. This gives you extra horsepower when using libraries like Animations, ngrx, and ReactiveForms.
79
+
80
+ ### `valueChanges()`
81
+
82
+ **What is it?** - Returns an Observable of data as a synchronized array of JSON objects. All Snapshot metadata is stripped and just the method provides only the data.
83
+
84
+ **Why would you use it?** - When you just need a list of data. No snapshot metadata is attached to the resulting array which makes it simple to render to a view.
85
+
86
+ **When would you not use it?** - When you need a more complex data structure than an array or you need the `key` of each snapshot for data manipulation methods. This method assumes you either are saving the `key` for the snapshot data or using a "readonly" approach.
87
+
88
+ ### `snapshotChanges()`
89
+
90
+ **What is it?** - Returns an Observable of data as a synchronized array of `AngularFireAction<DatabaseSnapshot>[]`.
91
+
92
+ **Why would you use it?** - When you need a list of data but also want to keep around metadata. Metadata provides you the underyling `DatabaseReference` and snapshot key. Having the snapshot's `key` around makes it easier to use data manipulation methods. This method gives you more horsepower with other Angular integrations such as ngrx, forms, and animations due to the `type` property. The `type` property on each `AngularFireAction` is useful for ngrx reducers, form states, and animation states.
93
+
94
+ **When would you not use it?** - When you need a more complex data structure than an array or if you need to process changes as they occur. This array is synchronized with the remote and local changes in the Firebase Database.
95
+
96
+ ### `stateChanges()`
97
+
98
+ **What is it?** - Returns an Observable of the most recent change as an `AngularFireAction`.
99
+
100
+ **Why would you use it?** - The above methods return a singular `AngularFireAction` from each child event that occurs. `stateChanges()` emits changes as they occur rather than syncing the query order. This works well for ngrx integrations as you can build your own data structure in your reducer methods.
101
+
102
+ **When would you not use it?** - When you just need a list of data. This is a more advanced usage of `AngularFireDatabase`.
103
+
104
+ ### `auditTrail()`
105
+
106
+ **What is it?** - Returns an Observable of `AngularFireAction[]` as they occur. Similar to `stateChanges()`, but instead it keeps around the trail of events as an array.
107
+
108
+ **Why would you use it?** - This method is like `stateChanges()` except it is not ephemeral. It collects each change in an array as they occur. This is useful for ngrx integrations where you need to replay the entire state of an application. This also works as a great debugging tool for all applications. You can simple write `db.list('items').auditTrail().subscribe(console.log)` and check the events in the console as they occur.
109
+
110
+ **When would you not use it?** - When you just need a list of data. This is a more advanced usage of AngularFireDatabase.
111
+
112
+ ### Limiting events
113
+
114
+ There are four child events: `"child_added"`, `"child_changed"`, `"child_removed"`, and `"child_moved"`. Each streaming method listens to all four by default. However, your site may only be intrested in one of these events. You can specify which events you'd like to use through the first parameter of each method:
115
+
116
+ ```ts
117
+ this.itemsRef = db.list('items');
118
+ this.itemsRef.snapshotChanges(['child_added'])
119
+ .subscribe(actions => {
120
+ actions.forEach(action => {
121
+ console.log(action.type);
122
+ console.log(action.key);
123
+ console.log(action.payload.val());
124
+ });
125
+ });
126
+ ```
127
+
128
+ ## Saving data
129
+
130
+ ### API Summary
131
+
132
+ The table below highlights some of the common methods on the `AngularFireList`.
133
+
134
+ | method | |
135
+ | ---------|--------------------|
136
+ | `push(value: T)` | Creates a new record on the list, using the Realtime Database's push-ids. |
137
+ | `update(keyRefOrSnap: string, value: T)` | Firebase | AFUnwrappedSnapshot, value: Object) | Updates an existing item in the array. Accepts a key, database reference, or an unwrapped snapshot. |
138
+ | `remove(key: string?)` | Deletes the item by key. If no parameter is provided, the entire list will be deleted. |
139
+
140
+ ## Returning promises
141
+
142
+ Each data operation method in the table above returns a promise. However,
143
+ you should rarely need to use the completion promise to indicate success,
144
+ because the realtime database keeps the list in sync.
145
+
146
+ The promise can be useful to chain multiple operations, catching possible errors
147
+ from security rules denials, or for debugging.
148
+
149
+ ```ts
150
+ const promise = db.list('items').remove();
151
+ promise
152
+ .then(_ => console.log('success'))
153
+ .catch(err => console.log(err, 'You do not have access!'));
154
+ ```
155
+
156
+ ### Adding new items
157
+
158
+ Use the `push()` method to add new items on the list.
159
+
160
+ ```ts
161
+ const itemsRef = db.list('items');
162
+ itemsRef.push({ name: newName });
163
+ ```
164
+
165
+ ### Replacing items in the list using `set`
166
+
167
+ Use the `set()` method to update existing items.
168
+
169
+ ```ts
170
+ const itemsRef = db.list('items');
171
+ // to get a key, check the Example app below
172
+ itemsRef.set('key-of-some-data', { size: newSize });
173
+ ```
174
+
175
+ Replaces the current value in the database with the new value specified as the parameter. This is called a destructive update, because it deletes everything currently in place and saves the new value.
176
+
177
+ ### Updating items in the list using `update`
178
+
179
+ Use the `update()` method to update existing items.
180
+
181
+ ```ts
182
+ const itemsRef = db.list('items');
183
+ // to get a key, check the Example app below
184
+ itemsRef.update('key-of-some-data', { size: newSize });
185
+ ```
186
+
187
+ Note that this updates the current value with in the database with the new value specified as the parameter. This is called a non-destructive update, because it only updates the values specified.
188
+
189
+ ### Removing items from the list
190
+ Use the `remove()` method to remove data at the list item's location.
191
+
192
+ ```ts
193
+ const itemsRef = db.list('items');
194
+ // to get a key, check the Example app below
195
+ itemsRef.remove('key-of-some-data');
196
+ ```
197
+
198
+ ## Deleting the entire list
199
+
200
+ If you omit the `key` parameter from `.remove()` it deletes the entire list.
201
+
202
+ ```ts
203
+ const itemsRef = db.list('items');
204
+ itemsRef.remove();
205
+ ```
206
+
207
+ ### Example
208
+
209
+ ```ts
210
+ import { Component } from '@angular/core';
211
+ import { AngularFireDatabase, AngularFireList } from '@angular/fire/compat/database';
212
+ import { Observable } from 'rxjs';
213
+ import { map } from 'rxjs/operators';
214
+
215
+ @Component({
216
+ selector: 'app-root',
217
+ template: `
218
+ <ul>
219
+ <li *ngFor="let item of items | async">
220
+ <input type="text" #updatetext [value]="item.text" />
221
+ <button (click)="updateItem(item.key, updatetext.value)">Update</button>
222
+ <button (click)="deleteItem(item.key)">Delete</button>
223
+ </li>
224
+ </ul>
225
+ <input type="text" #newitem />
226
+ <button (click)="addItem(newitem.value)">Add</button>
227
+ <button (click)="deleteEverything()">Delete All</button>
228
+ `,
229
+ })
230
+ export class AppComponent {
231
+ itemsRef: AngularFireList<any>;
232
+ items: Observable<any[]>;
233
+ constructor(db: AngularFireDatabase) {
234
+ this.itemsRef = db.list('messages');
235
+ // Use snapshotChanges().map() to store the key
236
+ this.items = this.itemsRef.snapshotChanges().pipe(
237
+ map(changes =>
238
+ changes.map(c => ({ key: c.payload.key, ...c.payload.val() }))
239
+ )
240
+ );
241
+ }
242
+ addItem(newName: string) {
243
+ this.itemsRef.push({ text: newName });
244
+ }
245
+ updateItem(key: string, newText: string) {
246
+ this.itemsRef.update(key, { text: newText });
247
+ }
248
+ deleteItem(key: string) {
249
+ this.itemsRef.remove(key);
250
+ }
251
+ deleteEverything() {
252
+ this.itemsRef.remove();
253
+ }
254
+ }
255
+ ```
256
+
257
+ ### [Next Step: Querying lists](querying-lists.md)
@@ -0,0 +1,182 @@
1
+ # 2. Retrieving data as objects
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
+ > The `AngularFireObject` is a service for manipulating and streaming object data.
6
+
7
+ The `AngularFireObject` service is not created by itself, but through the `AngularFireDatabase` service.
8
+
9
+ The guide below demonstrates how to retrieve, save, and remove data as objects.
10
+
11
+ ## Injecting the `AngularFireDatabase` service
12
+
13
+ **Make sure you have bootstrapped your application for AngularFire. See the Installation guide for bootstrap setup.**
14
+
15
+ `AngularFireDatabase` is a service which can be injected through the constructor of your Angular component or `@Injectable()` service.
16
+
17
+ If you've followed the earlier step "Installation and Setup" your `/src/app/app.component.ts` should look like below.
18
+
19
+ ```ts
20
+ import { Component } from '@angular/core';
21
+ import { AngularFireDatabase } from '@angular/fire/compat/database';
22
+ import { Observable } from 'rxjs';
23
+
24
+ @Component({
25
+ selector: 'app-root',
26
+ templateUrl: 'app.component.html',
27
+ styleUrls: ['app.component.css']
28
+ })
29
+ export class AppComponent {
30
+ items: Observable<any[]>;
31
+ constructor(db: AngularFireDatabase) {
32
+ this.items = db.list('items').valueChanges();
33
+ }
34
+ }
35
+ ```
36
+
37
+ In this section, we're going to modify the `/src/app/app.component.ts` to retrieve data as object.
38
+
39
+ ## Create an object binding
40
+
41
+ ```ts
42
+ const relative = db.object('item').valueChanges();
43
+ ```
44
+
45
+ ### Retrieve data
46
+
47
+ To get the object in realtime, create an object binding as a property of your component or service.
48
+
49
+ Then in your template, you can use the `async` pipe to unwrap the binding.
50
+
51
+ ```ts
52
+ import { Component } from '@angular/core';
53
+ import { AngularFireDatabase } from '@angular/fire/compat/database';
54
+ import { Observable } from 'rxjs';
55
+
56
+ @Component({
57
+ selector: 'app-root',
58
+ template: `
59
+ <h1>{{ (item | async)?.name }}</h1>
60
+ `,
61
+ })
62
+ export class AppComponent {
63
+ item: Observable<any>;
64
+ constructor(db: AngularFireDatabase) {
65
+ this.item = db.object('item').valueChanges();
66
+ }
67
+ }
68
+ ```
69
+
70
+ ## Saving data
71
+
72
+ ### API Summary
73
+
74
+ The table below highlights some of the common methods on the `AngularFireObject`.
75
+
76
+ | method | |
77
+ | ---------|--------------------|
78
+ | `set(value: T)` | Replaces the current value in the database with the new value specified as the parameter. This is called a **destructive** update, because it deletes everything currently in place and saves the new value. |
79
+ | `update(value: T)` | Updates the current value with in the database with the new value specified as the parameter. This is called a **non-destructive** update, because it only updates the values specified. |
80
+ | `remove()` | Deletes all data present at that location. Same as calling `set(null)`. |
81
+
82
+ ## Returning promises
83
+
84
+ Each data operation method in the table above returns a promise. However,
85
+ you should rarely need to use the completion promise to indicate success,
86
+ because the realtime database keeps the object in sync.
87
+
88
+ The promise can be useful to chain multiple operations, catching possible errors from security rules denials, or for debugging.
89
+
90
+ ```ts
91
+ const promise = db.object('item').remove();
92
+ promise
93
+ .then(_ => console.log('success'))
94
+ .catch(err => console.log(err, 'You dont have access!'));
95
+ ```
96
+
97
+ ### Saving data
98
+
99
+ Use the `set()` method for **destructive updates**.
100
+
101
+ ```ts
102
+ const itemRef = db.object('item');
103
+ itemRef.set({ name: 'new name!'});
104
+ ```
105
+
106
+ ### Updating data
107
+
108
+ Use the `update()` method for **non-destructive updates**.
109
+
110
+ ```ts
111
+ const itemRef = db.object('item');
112
+ itemRef.update({ age: newAge });
113
+ ```
114
+
115
+ **Only objects are allowed for updates, not primitives**. This is because
116
+ using an update with a primitive is the exact same as doing a `.set()` with a primitive.
117
+
118
+ ### Deleting data
119
+
120
+ Use the `remove()` method to remove data at the object's location.
121
+
122
+ ```ts
123
+ const itemRef = db.object('item');
124
+ itemRef.remove();
125
+ ```
126
+
127
+ **Example app**:
128
+
129
+ ```ts
130
+ import { Component } from '@angular/core';
131
+ import { AngularFireDatabase, AngularFireObject } from '@angular/fire/compat/database';
132
+ import { Observable } from 'rxjs';
133
+
134
+ @Component({
135
+ selector: 'app-root',
136
+ template: `
137
+ <h1>{{ item | async | json }}</h1>
138
+ <input type="text" #newname placeholder="Name" />
139
+ <input type="text" #newsize placeholder="Size" />
140
+ <br />
141
+ <button (click)="save(newname.value)">Set Name</button>
142
+ <button (click)="update(newsize.value)">Update Size</button>
143
+ <button (click)="delete()">Delete</button>
144
+ `,
145
+ })
146
+ export class AppComponent {
147
+ itemRef: AngularFireObject<any>;
148
+ item: Observable<any>;
149
+ constructor(db: AngularFireDatabase) {
150
+ this.itemRef = db.object('item');
151
+ this.item = this.itemRef.valueChanges();
152
+ }
153
+ save(newName: string) {
154
+ this.itemRef.set({ name: newName });
155
+ }
156
+ update(newSize: string) {
157
+ this.itemRef.update({ size: newSize });
158
+ }
159
+ delete() {
160
+ this.itemRef.remove();
161
+ }
162
+ }
163
+ ```
164
+
165
+ ## Retrieving the snapshot
166
+
167
+ AngularFire `valueChanges()` unwraps the Firebase DataSnapshot by default, but you can get the data as the original snapshot by using the `snapshotChanges()` option.
168
+
169
+ ```ts
170
+ this.itemRef = db.object('item');
171
+ this.itemRef.snapshotChanges().subscribe(action => {
172
+ console.log(action.type);
173
+ console.log(action.key)
174
+ console.log(action.payload.val())
175
+ });
176
+ ```
177
+
178
+ ## Querying?
179
+
180
+ Because `AngularFireObject` synchronizes objects from the realtime database, sorting will have no effect for queries that are not also limited by a range. For example, when paginating you would provide a query with a sort and filter. Both the sort operation and the filter operation affect which subset of the data is returned by the query; however, because the resulting object is simply json, the sort order will not be preseved locally. Hence, for operations that require sorting, you are probably looking for a [list](lists.md)
181
+
182
+ ### [Next Step: Retrieving data as lists](lists.md)
@@ -0,0 +1,155 @@
1
+ # 4. Querying lists
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
+ ## Creating a query with primitive/scalar values
6
+
7
+ Queries are created by building on the [`firebase.database.Reference`](https://firebase.google.com/docs/reference/js/firebase.database.Reference).
8
+
9
+ ```ts
10
+ db.list('/items', ref => ref.orderByChild('size').equalTo('large'))
11
+ ```
12
+
13
+ ### Query options
14
+
15
+ | Method | Purpose |
16
+ | ---------|--------------------|
17
+ | `orderByChild` | Specify a child to order by. |
18
+ | `orderByKey` | Boolean to order by Firebase Database keys. |
19
+ | `orderByValue` | Specify a value to order by. |
20
+ | ~~`orderByPriority`~~<sup>1</sup> | Boolean to order by Firebase Database priority.|
21
+ | `equalTo`<sup>2</sup> | Limit list to items that contain certain value. |
22
+ | `limitToFirst` | Sets the maximum number of items to return from the beginning of the ordered list of results. |
23
+ | `limitToLast` | Sets the maximum number of items to return from the end of the ordered list of results. |
24
+ | `startAt`<sup>2</sup> | Return items greater than or equal to the specified key or value, depending on the order-by method chosen. |
25
+ | `endAt`<sup>2</sup> | Return items less than or equal to the specified key or value, depending on the order-by method chosen. |
26
+
27
+ <sup>1</sup> [This is the old way of doing things and is no longer recommended for use](https://youtu.be/3WTQZV5-roY?t=3m). Anything you can achieve with `orderByPriority` you should be doing with `orderByChild`.
28
+
29
+ <sup>2</sup> The Firebase SDK supports an optional `key` parameter for [`startAt`](https://firebase.google.com/docs/reference/js/firebase.database.Reference#startAt), [`endAt`](https://firebase.google.com/docs/reference/js/firebase.database.Reference#endAt), and [`equalTo`](https://firebase.google.com/docs/reference/js/firebase.database.Reference#equalTo) when ordering by child, value, or priority. You can specify the `key` parameter using an object literal that contains the `value` and the `key`. For example: `startAt: { value: 'some-value', key: 'some-key' }`.
30
+
31
+ To learn more about how sorting and ordering data works in Firebase, check out the Firebase documentation on [working with lists of data](https://firebase.google.com/docs/database/web/lists-of-data#sorting_and_filtering_data).
32
+
33
+ ## Invalid query combinations
34
+
35
+ **Queries can only be ordered by one method.** This means you can only specify
36
+ `orderByChild`, `orderByKey`, `orderByPriority`, or `orderByValue`.
37
+
38
+ ```ts
39
+ // WARNING: Do not copy and paste. This will not work!
40
+ ref.orderByChild('size').equalTo('large').orderByKey(true)
41
+ ```
42
+
43
+ You can only use `limitToFirst` or `limitToLast`, but not both in combination.
44
+
45
+ ```ts
46
+ // WARNING: Do not copy and paste. This will not work!
47
+ ref.limitToFirst(10).limitToLast(100)
48
+ ```
49
+
50
+ ## Dynamic querying
51
+
52
+ To enable dynamic queries one should lean on RxJS Operators like `switchMap`.
53
+
54
+ An RxJS Subject is imported below. A Subject is like an Observable, but can multicast to many Observers. Subjects are like EventEmitters: they maintain a registry of many listeners. See, [What is a Subject](http://reactivex.io/rxjs/manual/overview.html#subject) for more information.
55
+
56
+ When we call [`switchMap` on the Subject](https://www.learnrxjs.io/operators/transformation/switchmap.html), we can map each value to a new Observable; in this case a database query.
57
+
58
+ ```ts
59
+ const size$ = new Subject<string>();
60
+ const queryObservable = size$.pipe(
61
+ switchMap(size =>
62
+ db.list('/items', ref => ref.orderByChild('size').equalTo(size)).valueChanges()
63
+ )
64
+ );
65
+
66
+ // subscribe to changes
67
+ queryObservable.subscribe(queriedItems => {
68
+ console.log(queriedItems);
69
+ });
70
+
71
+ // trigger the query
72
+ size$.next('large');
73
+
74
+ // re-trigger the query!!!
75
+ size$.next('small');
76
+ ```
77
+
78
+ **Example app:**
79
+
80
+ [See this example in action on StackBlitz](https://stackblitz.com/edit/angularfire-db-api-s8ip7m).
81
+
82
+ ```ts
83
+ import { Component } from '@angular/core';
84
+ import { AngularFireDatabase, AngularFireAction } from '@angular/fire/compat/database';
85
+ import { Observable, Subscription, BehaviorSubject } from 'rxjs';
86
+ import { switchMap } from 'rxjs/operators';
87
+
88
+ @Component({
89
+ selector: 'app-root',
90
+ template: `
91
+ <h1>Firebase widgets!</h1>
92
+ <div *ngIf="items$ | async; let items; else loading">
93
+ <ul>
94
+ <li *ngFor="let item of items">
95
+ {{ item.payload.val().text }}
96
+ <code>{{ item.payload.key }}</code>
97
+ </li>
98
+ </ul>
99
+ <div *ngIf="items.length === 0">No results, try clearing filters</div>
100
+ </div>
101
+ <ng-template #loading>Loading&hellip;</ng-template>
102
+ <div>
103
+ <h4>Filter by size</h4>
104
+ <button (click)="filterBy('small')">Small</button>
105
+ <button (click)="filterBy('medium')">Medium</button>
106
+ <button (click)="filterBy('large')">Large</button>
107
+ <button (click)="filterBy('x-large')">Extra Large</button>
108
+ <button (click)="filterBy(null)" *ngIf="this.size$.getValue()">
109
+ <em>clear filter</em>
110
+ </button>
111
+ </div>
112
+ `,
113
+ })
114
+ export class AppComponent {
115
+ items$: Observable<AngularFireAction<firebase.database.DataSnapshot>[]>;
116
+ size$: BehaviorSubject<string|null>;
117
+
118
+ constructor(db: AngularFireDatabase) {
119
+ this.size$ = new BehaviorSubject(null);
120
+ this.items$ = this.size$.pipe(
121
+ switchMap(size =>
122
+ db.list('/items', ref =>
123
+ size ? ref.orderByChild('size').equalTo(size) : ref
124
+ ).snapshotChanges()
125
+ )
126
+ );
127
+ }
128
+ filterBy(size: string|null) {
129
+ this.size$.next(size);
130
+ }
131
+ }
132
+ ```
133
+
134
+ **To run the above example as is, you need to have sample data in you firebase database with the following structure:**
135
+
136
+ ```json
137
+ {
138
+ "items": {
139
+ "a" : {
140
+ "size" : "small",
141
+ "text" : "small thing"
142
+ },
143
+ "b" : {
144
+ "size" : "medium",
145
+ "text" : "medium sample"
146
+ },
147
+ "c" : {
148
+ "size" : "large",
149
+ "text" : "large widget"
150
+ }
151
+ }
152
+ }
153
+ ```
154
+
155
+ ### [Next Step: Getting started with Firebase Authentication](../auth/getting-started.md)