@angular/fire 18.0.0-canary.bfc27e2 → 18.0.0-canary.cd18129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/analytics/analytics.module.mjs +5 -5
- package/esm2022/analytics/screen-tracking.service.mjs +4 -4
- package/esm2022/analytics/user-tracking.service.mjs +4 -4
- package/esm2022/app/app.module.mjs +5 -5
- package/esm2022/app-check/app-check.module.mjs +5 -5
- package/esm2022/auth/auth.module.mjs +5 -5
- package/esm2022/auth-guard/auth-guard.mjs +4 -4
- package/esm2022/auth-guard/auth-guard.module.mjs +5 -5
- package/esm2022/compat/analytics/analytics.mjs +4 -4
- package/esm2022/compat/analytics/analytics.module.mjs +5 -5
- package/esm2022/compat/analytics/screen-tracking.service.mjs +4 -4
- package/esm2022/compat/analytics/user-tracking.service.mjs +4 -4
- package/esm2022/compat/auth/auth.mjs +4 -4
- package/esm2022/compat/auth/auth.module.mjs +5 -5
- package/esm2022/compat/auth-guard/auth-guard.mjs +4 -4
- package/esm2022/compat/auth-guard/auth-guard.module.mjs +5 -5
- package/esm2022/compat/database/database.mjs +4 -4
- package/esm2022/compat/database/database.module.mjs +5 -5
- package/esm2022/compat/firebase.app.module.mjs +5 -5
- package/esm2022/compat/firestore/firestore.mjs +4 -4
- package/esm2022/compat/firestore/firestore.module.mjs +5 -5
- package/esm2022/compat/functions/functions.mjs +4 -4
- package/esm2022/compat/functions/functions.module.mjs +5 -5
- package/esm2022/compat/messaging/messaging.mjs +4 -4
- package/esm2022/compat/messaging/messaging.module.mjs +5 -5
- package/esm2022/compat/performance/performance.mjs +4 -4
- package/esm2022/compat/performance/performance.module.mjs +5 -5
- package/esm2022/compat/performance/performance.service.mjs +4 -4
- package/esm2022/compat/remote-config/remote-config.mjs +4 -4
- package/esm2022/compat/remote-config/remote-config.module.mjs +5 -5
- package/esm2022/compat/storage/pipes/storageUrl.pipe.mjs +8 -8
- package/esm2022/compat/storage/storage.mjs +4 -4
- package/esm2022/compat/storage/storage.module.mjs +5 -5
- package/esm2022/database/database.module.mjs +5 -5
- package/esm2022/firestore/firestore.module.mjs +5 -5
- package/esm2022/firestore/lite/lite.module.mjs +5 -5
- package/esm2022/functions/functions.module.mjs +5 -5
- package/esm2022/messaging/messaging.module.mjs +5 -5
- package/esm2022/performance/performance.module.mjs +5 -5
- package/esm2022/remote-config/remote-config.module.mjs +5 -5
- package/esm2022/storage/storage.module.mjs +5 -5
- package/esm2022/vertexai-preview/vertexai.module.mjs +5 -5
- package/esm2022/zones.mjs +4 -4
- package/fesm2022/angular-fire-analytics.mjs +297 -410
- package/fesm2022/angular-fire-analytics.mjs.map +1 -7
- package/fesm2022/angular-fire-app-check.mjs +91 -162
- package/fesm2022/angular-fire-app-check.mjs.map +1 -7
- package/fesm2022/angular-fire-app.mjs +108 -181
- package/fesm2022/angular-fire-app.mjs.map +1 -7
- package/fesm2022/angular-fire-auth-guard.mjs +73 -83
- package/fesm2022/angular-fire-auth-guard.mjs.map +1 -7
- package/fesm2022/angular-fire-auth.mjs +142 -421
- package/fesm2022/angular-fire-auth.mjs.map +1 -7
- package/fesm2022/angular-fire-compat-analytics.mjs +271 -262
- package/fesm2022/angular-fire-compat-analytics.mjs.map +1 -7
- package/fesm2022/angular-fire-compat-auth-guard.mjs +72 -83
- package/fesm2022/angular-fire-compat-auth-guard.mjs.map +1 -7
- package/fesm2022/angular-fire-compat-auth.mjs +214 -215
- package/fesm2022/angular-fire-compat-auth.mjs.map +1 -7
- package/fesm2022/angular-fire-compat-database.mjs +378 -375
- package/fesm2022/angular-fire-compat-database.mjs.map +1 -7
- package/fesm2022/angular-fire-compat-firestore.mjs +677 -537
- package/fesm2022/angular-fire-compat-firestore.mjs.map +1 -7
- package/fesm2022/angular-fire-compat-functions.mjs +94 -98
- package/fesm2022/angular-fire-compat-functions.mjs.map +1 -7
- package/fesm2022/angular-fire-compat-messaging.mjs +107 -107
- package/fesm2022/angular-fire-compat-messaging.mjs.map +1 -7
- package/fesm2022/angular-fire-compat-performance.mjs +152 -158
- package/fesm2022/angular-fire-compat-performance.mjs.map +1 -7
- package/fesm2022/angular-fire-compat-remote-config.mjs +232 -216
- package/fesm2022/angular-fire-compat-remote-config.mjs.map +1 -7
- package/fesm2022/angular-fire-compat-storage.mjs +231 -226
- package/fesm2022/angular-fire-compat-storage.mjs.map +1 -7
- package/fesm2022/angular-fire-compat.mjs +153 -140
- package/fesm2022/angular-fire-compat.mjs.map +1 -7
- package/fesm2022/angular-fire-database.mjs +136 -376
- package/fesm2022/angular-fire-database.mjs.map +1 -7
- package/fesm2022/angular-fire-firestore-lite.mjs +139 -388
- package/fesm2022/angular-fire-firestore-lite.mjs.map +1 -7
- package/fesm2022/angular-fire-firestore.mjs +167 -526
- package/fesm2022/angular-fire-firestore.mjs.map +1 -7
- package/fesm2022/angular-fire-functions.mjs +93 -166
- package/fesm2022/angular-fire-functions.mjs.map +1 -7
- package/fesm2022/angular-fire-messaging.mjs +118 -196
- package/fesm2022/angular-fire-messaging.mjs.map +1 -7
- package/fesm2022/angular-fire-performance.mjs +104 -178
- package/fesm2022/angular-fire-performance.mjs.map +1 -7
- package/fesm2022/angular-fire-remote-config.mjs +132 -254
- package/fesm2022/angular-fire-remote-config.mjs.map +1 -7
- package/fesm2022/angular-fire-storage.mjs +105 -225
- package/fesm2022/angular-fire-storage.mjs.map +1 -7
- package/fesm2022/angular-fire-vertexai-preview.mjs +85 -146
- package/fesm2022/angular-fire-vertexai-preview.mjs.map +1 -7
- package/fesm2022/angular-fire.mjs +213 -183
- package/fesm2022/angular-fire.mjs.map +1 -7
- package/package.json +1 -1
|
@@ -1,571 +1,711 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import { isPlatformServer } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { InjectionToken, PLATFORM_ID, Injectable, Inject, Optional, NgModule } from '@angular/core';
|
|
4
|
+
import * as i1 from '@angular/fire';
|
|
5
|
+
import { keepUnstableUntilFirst, VERSION } from '@angular/fire';
|
|
6
|
+
import * as i3 from '@angular/fire/app-check';
|
|
7
|
+
import { ɵfirebaseAppFactory as _firebaseAppFactory, ɵcacheInstance as _cacheInstance, FIREBASE_OPTIONS, FIREBASE_APP_NAME } from '@angular/fire/compat';
|
|
8
|
+
import * as i2 from '@angular/fire/compat/auth';
|
|
9
|
+
import { ɵauthFactory as _authFactory, USE_EMULATOR as USE_EMULATOR$1, SETTINGS as SETTINGS$1, TENANT_ID, LANGUAGE_CODE, USE_DEVICE_LANGUAGE, PERSISTENCE } from '@angular/fire/compat/auth';
|
|
10
|
+
import { Observable, asyncScheduler, from, of } from 'rxjs';
|
|
11
|
+
import { startWith, pairwise, map, scan, distinctUntilChanged, filter } from 'rxjs/operators';
|
|
12
|
+
import 'firebase/compat/auth';
|
|
13
|
+
import 'firebase/compat/firestore';
|
|
14
|
+
import firebase from 'firebase/compat/app';
|
|
15
|
+
|
|
4
16
|
function _fromRef(ref, scheduler = asyncScheduler) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
return new Observable(subscriber => {
|
|
18
|
+
let unsubscribe;
|
|
19
|
+
if (scheduler != null) {
|
|
20
|
+
scheduler.schedule(() => {
|
|
21
|
+
unsubscribe = ref.onSnapshot({ includeMetadataChanges: true }, subscriber);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
unsubscribe = ref.onSnapshot({ includeMetadataChanges: true }, subscriber);
|
|
26
|
+
}
|
|
27
|
+
return () => {
|
|
28
|
+
if (unsubscribe != null) {
|
|
29
|
+
unsubscribe();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
});
|
|
20
33
|
}
|
|
21
34
|
function fromRef(ref, scheduler) {
|
|
22
|
-
|
|
35
|
+
return _fromRef(ref, scheduler);
|
|
23
36
|
}
|
|
24
37
|
function fromDocRef(ref, scheduler) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
return fromRef(ref, scheduler)
|
|
39
|
+
.pipe(startWith(undefined), pairwise(), map((snapshots) => {
|
|
40
|
+
const [priorPayload, payload] = snapshots;
|
|
41
|
+
if (!payload.exists) {
|
|
42
|
+
return { payload, type: 'removed' };
|
|
43
|
+
}
|
|
44
|
+
if (!priorPayload?.exists) {
|
|
45
|
+
return { payload, type: 'added' };
|
|
46
|
+
}
|
|
47
|
+
return { payload, type: 'modified' };
|
|
48
|
+
}));
|
|
35
49
|
}
|
|
36
50
|
function fromCollectionRef(ref, scheduler) {
|
|
37
|
-
|
|
51
|
+
return fromRef(ref, scheduler).pipe(map(payload => ({ payload, type: 'query' })));
|
|
38
52
|
}
|
|
39
53
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
54
|
+
/**
|
|
55
|
+
* AngularFirestoreDocument service
|
|
56
|
+
*
|
|
57
|
+
* This class creates a reference to a Firestore Document. A reference is provided in
|
|
58
|
+
* in the constructor. The class is generic which gives you type safety for data update
|
|
59
|
+
* methods and data streaming.
|
|
60
|
+
*
|
|
61
|
+
* This class uses Symbol.observable to transform into Observable using Observable.from().
|
|
62
|
+
*
|
|
63
|
+
* This class is rarely used directly and should be created from the AngularFirestore service.
|
|
64
|
+
*
|
|
65
|
+
* Example:
|
|
66
|
+
*
|
|
67
|
+
* const fakeStock = new AngularFirestoreDocument<Stock>(doc('stocks/FAKE'));
|
|
68
|
+
* await fakeStock.set({ name: 'FAKE', price: 0.01 });
|
|
69
|
+
* fakeStock.valueChanges().map(snap => {
|
|
70
|
+
* if(snap.exists) return snap.data();
|
|
71
|
+
* return null;
|
|
72
|
+
* }).subscribe(value => console.log(value));
|
|
73
|
+
* // OR! Transform using Observable.from() and the data is unwrapped for you
|
|
74
|
+
* Observable.from(fakeStock).subscribe(value => console.log(value));
|
|
75
|
+
*/
|
|
76
|
+
class AngularFirestoreDocument {
|
|
77
|
+
ref;
|
|
78
|
+
afs;
|
|
79
|
+
/**
|
|
80
|
+
* The constructor takes in a DocumentReference to provide wrapper methods
|
|
81
|
+
* for data operations, data streaming, and Symbol.observable.
|
|
82
|
+
*/
|
|
83
|
+
constructor(ref, afs) {
|
|
84
|
+
this.ref = ref;
|
|
85
|
+
this.afs = afs;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Create or overwrite a single document.
|
|
89
|
+
*/
|
|
90
|
+
set(data, options) {
|
|
91
|
+
return this.ref.set(data, options);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Update some fields of a document without overwriting the entire document.
|
|
95
|
+
*/
|
|
96
|
+
update(data) {
|
|
97
|
+
return this.ref.update(data);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Delete a document.
|
|
101
|
+
*/
|
|
102
|
+
delete() {
|
|
103
|
+
return this.ref.delete();
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Create a reference to a sub-collection given a path and an optional query
|
|
107
|
+
* function.
|
|
108
|
+
*/
|
|
109
|
+
collection(path, queryFn) {
|
|
110
|
+
const collectionRef = this.ref.collection(path);
|
|
111
|
+
const { ref, query } = associateQuery(collectionRef, queryFn);
|
|
112
|
+
return new AngularFirestoreCollection(ref, query, this.afs);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Listen to snapshot updates from the document.
|
|
116
|
+
*/
|
|
117
|
+
snapshotChanges() {
|
|
118
|
+
const scheduledFromDocRef$ = fromDocRef(this.ref, this.afs.schedulers.outsideAngular);
|
|
119
|
+
return scheduledFromDocRef$.pipe(keepUnstableUntilFirst);
|
|
120
|
+
}
|
|
121
|
+
valueChanges(options = {}) {
|
|
122
|
+
return this.snapshotChanges().pipe(map(({ payload }) => options.idField ? {
|
|
123
|
+
...payload.data(),
|
|
124
|
+
...{ [options.idField]: payload.id }
|
|
125
|
+
} : payload.data()));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Retrieve the document once.
|
|
129
|
+
*/
|
|
130
|
+
get(options) {
|
|
131
|
+
return from(this.ref.get(options)).pipe(keepUnstableUntilFirst);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
102
134
|
|
|
103
|
-
|
|
104
|
-
|
|
135
|
+
/**
|
|
136
|
+
* Return a stream of document changes on a query. These results are not in sort order but in
|
|
137
|
+
* order of occurence.
|
|
138
|
+
*/
|
|
105
139
|
function docChanges(query, scheduler) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
140
|
+
return fromCollectionRef(query, scheduler)
|
|
141
|
+
.pipe(startWith(undefined), pairwise(), map((actionTuple) => {
|
|
142
|
+
const [priorAction, action] = actionTuple;
|
|
143
|
+
const docChanges = action.payload.docChanges();
|
|
144
|
+
const actions = docChanges.map(change => ({ type: change.type, payload: change }));
|
|
145
|
+
// the metadata has changed from the prior emission
|
|
146
|
+
if (priorAction && JSON.stringify(priorAction.payload.metadata) !== JSON.stringify(action.payload.metadata)) {
|
|
147
|
+
// go through all the docs in payload and figure out which ones changed
|
|
148
|
+
action.payload.docs.forEach((currentDoc, currentIndex) => {
|
|
149
|
+
const docChange = docChanges.find(d => d.doc.ref.isEqual(currentDoc.ref));
|
|
150
|
+
const priorDoc = priorAction?.payload.docs.find(d => d.ref.isEqual(currentDoc.ref));
|
|
151
|
+
if (docChange && JSON.stringify(docChange.doc.metadata) === JSON.stringify(currentDoc.metadata) ||
|
|
152
|
+
!docChange && priorDoc && JSON.stringify(priorDoc.metadata) === JSON.stringify(currentDoc.metadata)) {
|
|
153
|
+
// document doesn't appear to have changed, don't log another action
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
// since the actions are processed in order just push onto the array
|
|
157
|
+
actions.push({
|
|
158
|
+
type: 'modified',
|
|
159
|
+
payload: {
|
|
160
|
+
oldIndex: currentIndex,
|
|
161
|
+
newIndex: currentIndex,
|
|
162
|
+
type: 'modified',
|
|
163
|
+
doc: currentDoc
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
});
|
|
125
168
|
}
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
return actions;
|
|
129
|
-
}));
|
|
169
|
+
return actions;
|
|
170
|
+
}));
|
|
130
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* Return a stream of document changes on a query. These results are in sort order.
|
|
174
|
+
*/
|
|
131
175
|
function sortedChanges(query, events, scheduler) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
// cut down on unneed change cycles
|
|
136
|
-
map3((changes) => changes.map((c) => ({ type: c.type, payload: c })))
|
|
137
|
-
);
|
|
176
|
+
return docChanges(query, scheduler)
|
|
177
|
+
.pipe(scan((current, changes) => combineChanges(current, changes.map(it => it.payload), events), []), distinctUntilChanged(), // cut down on unneed change cycles
|
|
178
|
+
map(changes => changes.map(c => ({ type: c.type, payload: c }))));
|
|
138
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Combines the total result set from the current set of changes from an incoming set
|
|
182
|
+
* of changes.
|
|
183
|
+
*/
|
|
139
184
|
function combineChanges(current, changes, events) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
185
|
+
changes.forEach(change => {
|
|
186
|
+
// skip unwanted change types
|
|
187
|
+
if (events.indexOf(change.type) > -1) {
|
|
188
|
+
current = combineChange(current, change);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
return current;
|
|
146
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Splice arguments on top of a sliced array, to break top-level ===
|
|
195
|
+
* this is useful for change-detection
|
|
196
|
+
*/
|
|
147
197
|
function sliceAndSplice(original, start, deleteCount, ...args) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
198
|
+
const returnArray = original.slice();
|
|
199
|
+
returnArray.splice(start, deleteCount, ...args);
|
|
200
|
+
return returnArray;
|
|
151
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Creates a new sorted array from a new change.
|
|
204
|
+
* Build our own because we allow filtering of action types ('added', 'removed', 'modified') before scanning
|
|
205
|
+
* and so we have greater control over change detection (by breaking ===)
|
|
206
|
+
*/
|
|
152
207
|
function combineChange(combined, change) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
208
|
+
switch (change.type) {
|
|
209
|
+
case 'added':
|
|
210
|
+
if (combined[change.newIndex] && combined[change.newIndex].doc.ref.isEqual(change.doc.ref)) {
|
|
211
|
+
// Not sure why the duplicates are getting fired
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
return sliceAndSplice(combined, change.newIndex, 0, change);
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
217
|
+
case 'modified':
|
|
218
|
+
if (combined[change.oldIndex] == null || combined[change.oldIndex].doc.ref.isEqual(change.doc.ref)) {
|
|
219
|
+
// When an item changes position we first remove it
|
|
220
|
+
// and then add it's new position
|
|
221
|
+
if (change.oldIndex !== change.newIndex) {
|
|
222
|
+
const copiedArray = combined.slice();
|
|
223
|
+
copiedArray.splice(change.oldIndex, 1);
|
|
224
|
+
copiedArray.splice(change.newIndex, 0, change);
|
|
225
|
+
return copiedArray;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
return sliceAndSplice(combined, change.newIndex, 1, change);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
break;
|
|
232
|
+
case 'removed':
|
|
233
|
+
if (combined[change.oldIndex] && combined[change.oldIndex].doc.ref.isEqual(change.doc.ref)) {
|
|
234
|
+
return sliceAndSplice(combined, change.oldIndex, 1);
|
|
235
|
+
}
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
return combined;
|
|
179
239
|
}
|
|
180
240
|
|
|
181
|
-
// collection/collection.mjs
|
|
182
|
-
import { keepUnstableUntilFirst as keepUnstableUntilFirst2 } from "@angular/fire";
|
|
183
|
-
import { from as from2 } from "rxjs";
|
|
184
|
-
import { filter, map as map4, pairwise as pairwise3, scan as scan2, startWith as startWith3 } from "rxjs/operators";
|
|
185
241
|
function validateEventsArray(events) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
242
|
+
if (!events || events.length === 0) {
|
|
243
|
+
events = ['added', 'removed', 'modified'];
|
|
244
|
+
}
|
|
245
|
+
return events;
|
|
190
246
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
247
|
+
/**
|
|
248
|
+
* AngularFirestoreCollection service
|
|
249
|
+
*
|
|
250
|
+
* This class creates a reference to a Firestore Collection. A reference and a query are provided in
|
|
251
|
+
* in the constructor. The query can be the unqueried reference if no query is desired.The class
|
|
252
|
+
* is generic which gives you type safety for data update methods and data streaming.
|
|
253
|
+
*
|
|
254
|
+
* This class uses Symbol.observable to transform into Observable using Observable.from().
|
|
255
|
+
*
|
|
256
|
+
* This class is rarely used directly and should be created from the AngularFirestore service.
|
|
257
|
+
*
|
|
258
|
+
* Example:
|
|
259
|
+
*
|
|
260
|
+
* const collectionRef = firebase.firestore.collection('stocks');
|
|
261
|
+
* const query = collectionRef.where('price', '>', '0.01');
|
|
262
|
+
* const fakeStock = new AngularFirestoreCollection<Stock>(collectionRef, query);
|
|
263
|
+
*
|
|
264
|
+
* // NOTE!: the updates are performed on the reference not the query
|
|
265
|
+
* await fakeStock.add({ name: 'FAKE', price: 0.01 });
|
|
266
|
+
*
|
|
267
|
+
* // Subscribe to changes as snapshots. This provides you data updates as well as delta updates.
|
|
268
|
+
* fakeStock.valueChanges().subscribe(value => console.log(value));
|
|
269
|
+
*/
|
|
270
|
+
class AngularFirestoreCollection {
|
|
271
|
+
ref;
|
|
272
|
+
query;
|
|
273
|
+
afs;
|
|
274
|
+
/**
|
|
275
|
+
* The constructor takes in a CollectionReference and Query to provide wrapper methods
|
|
276
|
+
* for data operations and data streaming.
|
|
277
|
+
*
|
|
278
|
+
* Note: Data operation methods are done on the reference not the query. This means
|
|
279
|
+
* when you update data it is not updating data to the window of your query unless
|
|
280
|
+
* the data fits the criteria of the query. See the AssociatedRefence type for details
|
|
281
|
+
* on this implication.
|
|
282
|
+
*/
|
|
283
|
+
constructor(ref, query, afs) {
|
|
284
|
+
this.ref = ref;
|
|
285
|
+
this.query = query;
|
|
286
|
+
this.afs = afs;
|
|
218
287
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
return
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
288
|
+
/**
|
|
289
|
+
* Listen to the latest change in the stream. This method returns changes
|
|
290
|
+
* as they occur and they are not sorted by query order. This allows you to construct
|
|
291
|
+
* your own data structure.
|
|
292
|
+
*/
|
|
293
|
+
stateChanges(events) {
|
|
294
|
+
let source = docChanges(this.query, this.afs.schedulers.outsideAngular);
|
|
295
|
+
if (events && events.length > 0) {
|
|
296
|
+
source = source.pipe(map(actions => actions.filter(change => events.indexOf(change.type) > -1)));
|
|
297
|
+
}
|
|
298
|
+
return source.pipe(
|
|
299
|
+
// We want to filter out empty arrays, but always emit at first, so the developer knows
|
|
300
|
+
// that the collection has been resolve; even if it's empty
|
|
301
|
+
startWith(undefined), pairwise(), filter(([prior, current]) => current.length > 0 || !prior), map(([, current]) => current), keepUnstableUntilFirst);
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Create a stream of changes as they occur it time. This method is similar to stateChanges()
|
|
305
|
+
* but it collects each event in an array over time.
|
|
306
|
+
*/
|
|
307
|
+
auditTrail(events) {
|
|
308
|
+
return this.stateChanges(events).pipe(scan((current, action) => [...current, ...action], []));
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Create a stream of synchronized changes. This method keeps the local array in sorted
|
|
312
|
+
* query order.
|
|
313
|
+
*/
|
|
314
|
+
snapshotChanges(events) {
|
|
315
|
+
const validatedEvents = validateEventsArray(events);
|
|
316
|
+
const scheduledSortedChanges$ = sortedChanges(this.query, validatedEvents, this.afs.schedulers.outsideAngular);
|
|
317
|
+
return scheduledSortedChanges$.pipe(keepUnstableUntilFirst);
|
|
318
|
+
}
|
|
319
|
+
valueChanges(options = {}) {
|
|
320
|
+
return fromCollectionRef(this.query, this.afs.schedulers.outsideAngular)
|
|
321
|
+
.pipe(map(actions => actions.payload.docs.map(a => {
|
|
322
|
+
if (options.idField) {
|
|
323
|
+
return {
|
|
324
|
+
...a.data(),
|
|
325
|
+
...{ [options.idField]: a.id }
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
return a.data();
|
|
330
|
+
}
|
|
331
|
+
})), keepUnstableUntilFirst);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Retrieve the results of the query once.
|
|
335
|
+
*/
|
|
336
|
+
get(options) {
|
|
337
|
+
return from(this.query.get(options)).pipe(keepUnstableUntilFirst);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Add data to a collection reference.
|
|
341
|
+
*
|
|
342
|
+
* Note: Data operation methods are done on the reference not the query. This means
|
|
343
|
+
* when you update data it is not updating data to the window of your query unless
|
|
344
|
+
* the data fits the criteria of the query.
|
|
345
|
+
*/
|
|
346
|
+
add(data) {
|
|
347
|
+
return this.ref.add(data);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Create a reference to a single document in a collection.
|
|
351
|
+
*/
|
|
352
|
+
doc(path) {
|
|
353
|
+
// TODO is there a better way to solve this type issue
|
|
354
|
+
return new AngularFirestoreDocument(this.ref.doc(path), this.afs);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
280
357
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
358
|
+
/**
|
|
359
|
+
* AngularFirestoreCollectionGroup service
|
|
360
|
+
*
|
|
361
|
+
* This class holds a reference to a Firestore Collection Group Query.
|
|
362
|
+
*
|
|
363
|
+
* This class uses Symbol.observable to transform into Observable using Observable.from().
|
|
364
|
+
*
|
|
365
|
+
* This class is rarely used directly and should be created from the AngularFirestore service.
|
|
366
|
+
*
|
|
367
|
+
* Example:
|
|
368
|
+
*
|
|
369
|
+
* const collectionGroup = firebase.firestore.collectionGroup('stocks');
|
|
370
|
+
* const query = collectionRef.where('price', '>', '0.01');
|
|
371
|
+
* const fakeStock = new AngularFirestoreCollectionGroup<Stock>(query, afs);
|
|
372
|
+
*
|
|
373
|
+
* // Subscribe to changes as snapshots. This provides you data updates as well as delta updates.
|
|
374
|
+
* fakeStock.valueChanges().subscribe(value => console.log(value));
|
|
375
|
+
*/
|
|
376
|
+
class AngularFirestoreCollectionGroup {
|
|
377
|
+
query;
|
|
378
|
+
afs;
|
|
379
|
+
/**
|
|
380
|
+
* The constructor takes in a CollectionGroupQuery to provide wrapper methods
|
|
381
|
+
* for data operations and data streaming.
|
|
382
|
+
*/
|
|
383
|
+
constructor(query, afs) {
|
|
384
|
+
this.query = query;
|
|
385
|
+
this.afs = afs;
|
|
304
386
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
}
|
|
387
|
+
/**
|
|
388
|
+
* Listen to the latest change in the stream. This method returns changes
|
|
389
|
+
* as they occur and they are not sorted by query order. This allows you to construct
|
|
390
|
+
* your own data structure.
|
|
391
|
+
*/
|
|
392
|
+
stateChanges(events) {
|
|
393
|
+
if (!events || events.length === 0) {
|
|
394
|
+
return docChanges(this.query, this.afs.schedulers.outsideAngular).pipe(keepUnstableUntilFirst);
|
|
395
|
+
}
|
|
396
|
+
return docChanges(this.query, this.afs.schedulers.outsideAngular)
|
|
397
|
+
.pipe(map(actions => actions.filter(change => events.indexOf(change.type) > -1)), filter(changes => changes.length > 0), keepUnstableUntilFirst);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Create a stream of changes as they occur it time. This method is similar to stateChanges()
|
|
401
|
+
* but it collects each event in an array over time.
|
|
402
|
+
*/
|
|
403
|
+
auditTrail(events) {
|
|
404
|
+
return this.stateChanges(events).pipe(scan((current, action) => [...current, ...action], []));
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Create a stream of synchronized changes. This method keeps the local array in sorted
|
|
408
|
+
* query order.
|
|
409
|
+
*/
|
|
410
|
+
snapshotChanges(events) {
|
|
411
|
+
const validatedEvents = validateEventsArray(events);
|
|
412
|
+
const scheduledSortedChanges$ = sortedChanges(this.query, validatedEvents, this.afs.schedulers.outsideAngular);
|
|
413
|
+
return scheduledSortedChanges$.pipe(keepUnstableUntilFirst);
|
|
414
|
+
}
|
|
415
|
+
valueChanges(options = {}) {
|
|
416
|
+
const fromCollectionRefScheduled$ = fromCollectionRef(this.query, this.afs.schedulers.outsideAngular);
|
|
417
|
+
return fromCollectionRefScheduled$
|
|
418
|
+
.pipe(map(actions => actions.payload.docs.map(a => {
|
|
419
|
+
if (options.idField) {
|
|
420
|
+
return {
|
|
421
|
+
[options.idField]: a.id,
|
|
422
|
+
...a.data()
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
return a.data();
|
|
427
|
+
}
|
|
428
|
+
})), keepUnstableUntilFirst);
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Retrieve the results of the query once.
|
|
432
|
+
*/
|
|
433
|
+
get(options) {
|
|
434
|
+
return from(this.query.get(options)).pipe(keepUnstableUntilFirst);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
343
437
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
438
|
+
/**
|
|
439
|
+
* The value of this token determines whether or not the firestore will have persistance enabled
|
|
440
|
+
*/
|
|
441
|
+
const ENABLE_PERSISTENCE = new InjectionToken('angularfire2.enableFirestorePersistence');
|
|
442
|
+
const PERSISTENCE_SETTINGS = new InjectionToken('angularfire2.firestore.persistenceSettings');
|
|
443
|
+
const SETTINGS = new InjectionToken('angularfire2.firestore.settings');
|
|
444
|
+
const USE_EMULATOR = new InjectionToken('angularfire2.firestore.use-emulator');
|
|
445
|
+
/**
|
|
446
|
+
* A utility methods for associating a collection reference with
|
|
447
|
+
* a query.
|
|
448
|
+
*
|
|
449
|
+
* @param collectionRef - A collection reference to query
|
|
450
|
+
* @param queryFn - The callback to create a query
|
|
451
|
+
*
|
|
452
|
+
* Example:
|
|
453
|
+
* const { query, ref } = associateQuery(docRef.collection('items'), ref => {
|
|
454
|
+
* return ref.where('age', '<', 200);
|
|
455
|
+
* });
|
|
456
|
+
*/
|
|
457
|
+
function associateQuery(collectionRef, queryFn = ref => ref) {
|
|
458
|
+
const query = queryFn(collectionRef);
|
|
459
|
+
const ref = collectionRef;
|
|
460
|
+
return { query, ref };
|
|
366
461
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
462
|
+
/**
|
|
463
|
+
* AngularFirestore Service
|
|
464
|
+
*
|
|
465
|
+
* This service is the main entry point for this feature module. It provides
|
|
466
|
+
* an API for creating Collection and Reference services. These services can
|
|
467
|
+
* then be used to do data updates and observable streams of the data.
|
|
468
|
+
*
|
|
469
|
+
* Example:
|
|
470
|
+
*
|
|
471
|
+
* import { Component } from '@angular/core';
|
|
472
|
+
* import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '@angular/fire/firestore';
|
|
473
|
+
* import { Observable } from 'rxjs/Observable';
|
|
474
|
+
* import { from } from 'rxjs/observable';
|
|
475
|
+
*
|
|
476
|
+
* @Component({
|
|
477
|
+
* selector: 'app-my-component',
|
|
478
|
+
* template: `
|
|
479
|
+
* <h2>Items for {{ (profile | async)?.name }}
|
|
480
|
+
* <ul>
|
|
481
|
+
* <li *ngFor="let item of items | async">{{ item.name }}</li>
|
|
482
|
+
* </ul>
|
|
483
|
+
* <div class="control-input">
|
|
484
|
+
* <input type="text" #itemname />
|
|
485
|
+
* <button (click)="addItem(itemname.value)">Add Item</button>
|
|
486
|
+
* </div>
|
|
487
|
+
* `
|
|
488
|
+
* })
|
|
489
|
+
* export class MyComponent implements OnInit {
|
|
490
|
+
*
|
|
491
|
+
* // services for data operations and data streaming
|
|
492
|
+
* private readonly itemsRef: AngularFirestoreCollection<Item>;
|
|
493
|
+
* private readonly profileRef: AngularFirestoreDocument<Profile>;
|
|
494
|
+
*
|
|
495
|
+
* // observables for template
|
|
496
|
+
* items: Observable<Item[]>;
|
|
497
|
+
* profile: Observable<Profile>;
|
|
498
|
+
*
|
|
499
|
+
* // inject main service
|
|
500
|
+
* constructor(private readonly afs: AngularFirestore) {}
|
|
501
|
+
*
|
|
502
|
+
* ngOnInit() {
|
|
503
|
+
* this.itemsRef = afs.collection('items', ref => ref.where('user', '==', 'davideast').limit(10));
|
|
504
|
+
* this.items = this.itemsRef.valueChanges().map(snap => snap.docs.map(data => doc.data()));
|
|
505
|
+
* // this.items = from(this.itemsRef); // you can also do this with no mapping
|
|
506
|
+
*
|
|
507
|
+
* this.profileRef = afs.doc('users/davideast');
|
|
508
|
+
* this.profile = this.profileRef.valueChanges();
|
|
509
|
+
* }
|
|
510
|
+
*
|
|
511
|
+
* addItem(name: string) {
|
|
512
|
+
* const user = 'davideast';
|
|
513
|
+
* this.itemsRef.add({ name, user });
|
|
514
|
+
* }
|
|
515
|
+
* }
|
|
516
|
+
*/
|
|
517
|
+
class AngularFirestore {
|
|
518
|
+
schedulers;
|
|
519
|
+
firestore;
|
|
520
|
+
persistenceEnabled$;
|
|
521
|
+
/**
|
|
522
|
+
* Each Feature of AngularFire has a FirebaseApp injected. This way we
|
|
523
|
+
* don't rely on the main Firebase App instance and we can create named
|
|
524
|
+
* apps and use multiple apps.
|
|
525
|
+
*/
|
|
526
|
+
constructor(options, name, shouldEnablePersistence, settings,
|
|
527
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
528
|
+
platformId, zone, schedulers, persistenceSettings, _useEmulator, auth, useAuthEmulator, authSettings, // can't use firebase.auth.AuthSettings here
|
|
529
|
+
tenantId, languageCode, useDeviceLanguage, persistence, _appCheckInstances) {
|
|
530
|
+
this.schedulers = schedulers;
|
|
531
|
+
const app = _firebaseAppFactory(options, zone, name);
|
|
532
|
+
const useEmulator = _useEmulator;
|
|
533
|
+
if (auth) {
|
|
534
|
+
_authFactory(app, zone, useAuthEmulator, tenantId, languageCode, useDeviceLanguage, authSettings, persistence);
|
|
535
|
+
}
|
|
536
|
+
[this.firestore, this.persistenceEnabled$] = _cacheInstance(`${app.name}.firestore`, 'AngularFirestore', app.name, () => {
|
|
537
|
+
const firestore = zone.runOutsideAngular(() => app.firestore());
|
|
538
|
+
if (settings) {
|
|
539
|
+
firestore.settings(settings);
|
|
398
540
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
541
|
+
if (useEmulator) {
|
|
542
|
+
firestore.useEmulator(...useEmulator);
|
|
543
|
+
}
|
|
544
|
+
if (shouldEnablePersistence && !isPlatformServer(platformId)) {
|
|
545
|
+
// We need to try/catch here because not all enablePersistence() failures are caught
|
|
546
|
+
// https://github.com/firebase/firebase-js-sdk/issues/608
|
|
547
|
+
const enablePersistence = () => {
|
|
548
|
+
try {
|
|
549
|
+
return from(firestore.enablePersistence(persistenceSettings || undefined).then(() => true, () => false));
|
|
550
|
+
}
|
|
551
|
+
catch (e) {
|
|
552
|
+
if (typeof console !== 'undefined') {
|
|
553
|
+
console.warn(e);
|
|
554
|
+
}
|
|
555
|
+
return of(false);
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
return [firestore, zone.runOutsideAngular(enablePersistence)];
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
return [firestore, of(false)];
|
|
562
|
+
}
|
|
563
|
+
}, [settings, useEmulator, shouldEnablePersistence]);
|
|
564
|
+
}
|
|
565
|
+
collection(pathOrRef, queryFn) {
|
|
566
|
+
let collectionRef;
|
|
567
|
+
if (typeof pathOrRef === 'string') {
|
|
568
|
+
collectionRef = this.firestore.collection(pathOrRef);
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
collectionRef = pathOrRef;
|
|
572
|
+
}
|
|
573
|
+
const { ref, query } = associateQuery(collectionRef, queryFn);
|
|
574
|
+
const refInZone = this.schedulers.ngZone.run(() => ref);
|
|
575
|
+
return new AngularFirestoreCollection(refInZone, query, this);
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Create a reference to a Firestore Collection Group based on a collectionId
|
|
579
|
+
* and an optional query function to narrow the result
|
|
580
|
+
* set.
|
|
581
|
+
*/
|
|
582
|
+
collectionGroup(collectionId, queryGroupFn) {
|
|
583
|
+
const queryFn = queryGroupFn || (ref => ref);
|
|
584
|
+
const collectionGroup = this.firestore.collectionGroup(collectionId);
|
|
585
|
+
return new AngularFirestoreCollectionGroup(queryFn(collectionGroup), this);
|
|
414
586
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
const queryFn = queryGroupFn || ((ref) => ref);
|
|
426
|
-
const collectionGroup = this.firestore.collectionGroup(collectionId);
|
|
427
|
-
return new AngularFirestoreCollectionGroup(queryFn(collectionGroup), this);
|
|
428
|
-
}
|
|
429
|
-
doc(pathOrRef) {
|
|
430
|
-
let ref;
|
|
431
|
-
if (typeof pathOrRef === "string") {
|
|
432
|
-
ref = this.firestore.doc(pathOrRef);
|
|
433
|
-
} else {
|
|
434
|
-
ref = pathOrRef;
|
|
587
|
+
doc(pathOrRef) {
|
|
588
|
+
let ref;
|
|
589
|
+
if (typeof pathOrRef === 'string') {
|
|
590
|
+
ref = this.firestore.doc(pathOrRef);
|
|
591
|
+
}
|
|
592
|
+
else {
|
|
593
|
+
ref = pathOrRef;
|
|
594
|
+
}
|
|
595
|
+
const refInZone = this.schedulers.ngZone.run(() => ref);
|
|
596
|
+
return new AngularFirestoreDocument(refInZone, this);
|
|
435
597
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
}],
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
}, {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}, {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}, {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
}] }, { type:
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
}, {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
}, {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
}, {
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
}, {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
}, {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
}, {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}, {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
}, {
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
598
|
+
/**
|
|
599
|
+
* Returns a generated Firestore Document Id.
|
|
600
|
+
*/
|
|
601
|
+
createId() {
|
|
602
|
+
return this.firestore.collection('_').doc().id;
|
|
603
|
+
}
|
|
604
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: AngularFirestore, deps: [{ token: FIREBASE_OPTIONS }, { token: FIREBASE_APP_NAME, optional: true }, { token: ENABLE_PERSISTENCE, optional: true }, { token: SETTINGS, optional: true }, { token: PLATFORM_ID }, { token: i0.NgZone }, { token: i1.ɵAngularFireSchedulers }, { token: PERSISTENCE_SETTINGS, optional: true }, { token: USE_EMULATOR, optional: true }, { token: i2.AngularFireAuth, optional: true }, { token: USE_EMULATOR$1, optional: true }, { token: SETTINGS$1, optional: true }, { token: TENANT_ID, optional: true }, { token: LANGUAGE_CODE, optional: true }, { token: USE_DEVICE_LANGUAGE, optional: true }, { token: PERSISTENCE, optional: true }, { token: i3.AppCheckInstances, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
605
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: AngularFirestore, providedIn: 'any' });
|
|
606
|
+
}
|
|
607
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: AngularFirestore, decorators: [{
|
|
608
|
+
type: Injectable,
|
|
609
|
+
args: [{
|
|
610
|
+
providedIn: 'any'
|
|
611
|
+
}]
|
|
612
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
613
|
+
type: Inject,
|
|
614
|
+
args: [FIREBASE_OPTIONS]
|
|
615
|
+
}] }, { type: undefined, decorators: [{
|
|
616
|
+
type: Optional
|
|
617
|
+
}, {
|
|
618
|
+
type: Inject,
|
|
619
|
+
args: [FIREBASE_APP_NAME]
|
|
620
|
+
}] }, { type: undefined, decorators: [{
|
|
621
|
+
type: Optional
|
|
622
|
+
}, {
|
|
623
|
+
type: Inject,
|
|
624
|
+
args: [ENABLE_PERSISTENCE]
|
|
625
|
+
}] }, { type: undefined, decorators: [{
|
|
626
|
+
type: Optional
|
|
627
|
+
}, {
|
|
628
|
+
type: Inject,
|
|
629
|
+
args: [SETTINGS]
|
|
630
|
+
}] }, { type: Object, decorators: [{
|
|
631
|
+
type: Inject,
|
|
632
|
+
args: [PLATFORM_ID]
|
|
633
|
+
}] }, { type: i0.NgZone }, { type: i1.ɵAngularFireSchedulers }, { type: undefined, decorators: [{
|
|
634
|
+
type: Optional
|
|
635
|
+
}, {
|
|
636
|
+
type: Inject,
|
|
637
|
+
args: [PERSISTENCE_SETTINGS]
|
|
638
|
+
}] }, { type: undefined, decorators: [{
|
|
639
|
+
type: Optional
|
|
640
|
+
}, {
|
|
641
|
+
type: Inject,
|
|
642
|
+
args: [USE_EMULATOR]
|
|
643
|
+
}] }, { type: i2.AngularFireAuth, decorators: [{
|
|
644
|
+
type: Optional
|
|
645
|
+
}] }, { type: undefined, decorators: [{
|
|
646
|
+
type: Optional
|
|
647
|
+
}, {
|
|
648
|
+
type: Inject,
|
|
649
|
+
args: [USE_EMULATOR$1]
|
|
650
|
+
}] }, { type: undefined, decorators: [{
|
|
651
|
+
type: Optional
|
|
652
|
+
}, {
|
|
653
|
+
type: Inject,
|
|
654
|
+
args: [SETTINGS$1]
|
|
655
|
+
}] }, { type: undefined, decorators: [{
|
|
656
|
+
type: Optional
|
|
657
|
+
}, {
|
|
658
|
+
type: Inject,
|
|
659
|
+
args: [TENANT_ID]
|
|
660
|
+
}] }, { type: undefined, decorators: [{
|
|
661
|
+
type: Optional
|
|
662
|
+
}, {
|
|
663
|
+
type: Inject,
|
|
664
|
+
args: [LANGUAGE_CODE]
|
|
665
|
+
}] }, { type: undefined, decorators: [{
|
|
666
|
+
type: Optional
|
|
667
|
+
}, {
|
|
668
|
+
type: Inject,
|
|
669
|
+
args: [USE_DEVICE_LANGUAGE]
|
|
670
|
+
}] }, { type: undefined, decorators: [{
|
|
671
|
+
type: Optional
|
|
672
|
+
}, {
|
|
673
|
+
type: Inject,
|
|
674
|
+
args: [PERSISTENCE]
|
|
675
|
+
}] }, { type: i3.AppCheckInstances, decorators: [{
|
|
676
|
+
type: Optional
|
|
677
|
+
}] }] });
|
|
678
|
+
|
|
679
|
+
class AngularFirestoreModule {
|
|
680
|
+
constructor() {
|
|
681
|
+
firebase.registerVersion('angularfire', VERSION.full, 'fst-compat');
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Attempt to enable persistent storage, if possible
|
|
685
|
+
*/
|
|
686
|
+
static enablePersistence(persistenceSettings) {
|
|
687
|
+
return {
|
|
688
|
+
ngModule: AngularFirestoreModule,
|
|
689
|
+
providers: [
|
|
690
|
+
{ provide: ENABLE_PERSISTENCE, useValue: true },
|
|
691
|
+
{ provide: PERSISTENCE_SETTINGS, useValue: persistenceSettings },
|
|
692
|
+
]
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: AngularFirestoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
696
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.0.0", ngImport: i0, type: AngularFirestoreModule });
|
|
697
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: AngularFirestoreModule, providers: [AngularFirestore] });
|
|
698
|
+
}
|
|
699
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: AngularFirestoreModule, decorators: [{
|
|
700
|
+
type: NgModule,
|
|
701
|
+
args: [{
|
|
702
|
+
providers: [AngularFirestore]
|
|
703
|
+
}]
|
|
704
|
+
}], ctorParameters: () => [] });
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* Generated bundle index. Do not edit.
|
|
708
|
+
*/
|
|
519
709
|
|
|
520
|
-
|
|
521
|
-
import { NgModule } from "@angular/core";
|
|
522
|
-
import { VERSION } from "@angular/fire";
|
|
523
|
-
import firebase from "firebase/compat/app";
|
|
524
|
-
import * as i02 from "@angular/core";
|
|
525
|
-
var AngularFirestoreModule = class _AngularFirestoreModule {
|
|
526
|
-
constructor() {
|
|
527
|
-
firebase.registerVersion("angularfire", VERSION.full, "fst-compat");
|
|
528
|
-
}
|
|
529
|
-
/**
|
|
530
|
-
* Attempt to enable persistent storage, if possible
|
|
531
|
-
*/
|
|
532
|
-
static enablePersistence(persistenceSettings) {
|
|
533
|
-
return {
|
|
534
|
-
ngModule: _AngularFirestoreModule,
|
|
535
|
-
providers: [
|
|
536
|
-
{ provide: ENABLE_PERSISTENCE, useValue: true },
|
|
537
|
-
{ provide: PERSISTENCE_SETTINGS, useValue: persistenceSettings }
|
|
538
|
-
]
|
|
539
|
-
};
|
|
540
|
-
}
|
|
541
|
-
static ɵfac = i02.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.0-rc.3", ngImport: i02, type: _AngularFirestoreModule, deps: [], target: i02.ɵɵFactoryTarget.NgModule });
|
|
542
|
-
static ɵmod = i02.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.0.0-rc.3", ngImport: i02, type: _AngularFirestoreModule });
|
|
543
|
-
static ɵinj = i02.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.0.0-rc.3", ngImport: i02, type: _AngularFirestoreModule, providers: [AngularFirestore] });
|
|
544
|
-
};
|
|
545
|
-
i02.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.0-rc.3", ngImport: i02, type: AngularFirestoreModule, decorators: [{
|
|
546
|
-
type: NgModule,
|
|
547
|
-
args: [{
|
|
548
|
-
providers: [AngularFirestore]
|
|
549
|
-
}]
|
|
550
|
-
}], ctorParameters: () => [] });
|
|
551
|
-
export {
|
|
552
|
-
AngularFirestore,
|
|
553
|
-
AngularFirestoreCollection,
|
|
554
|
-
AngularFirestoreCollectionGroup,
|
|
555
|
-
AngularFirestoreDocument,
|
|
556
|
-
AngularFirestoreModule,
|
|
557
|
-
ENABLE_PERSISTENCE,
|
|
558
|
-
PERSISTENCE_SETTINGS,
|
|
559
|
-
SETTINGS,
|
|
560
|
-
USE_EMULATOR,
|
|
561
|
-
associateQuery,
|
|
562
|
-
combineChange,
|
|
563
|
-
combineChanges,
|
|
564
|
-
docChanges,
|
|
565
|
-
fromCollectionRef,
|
|
566
|
-
fromDocRef,
|
|
567
|
-
fromRef,
|
|
568
|
-
sortedChanges,
|
|
569
|
-
validateEventsArray
|
|
570
|
-
};
|
|
710
|
+
export { AngularFirestore, AngularFirestoreCollection, AngularFirestoreCollectionGroup, AngularFirestoreDocument, AngularFirestoreModule, ENABLE_PERSISTENCE, PERSISTENCE_SETTINGS, SETTINGS, USE_EMULATOR, associateQuery, combineChange, combineChanges, docChanges, fromCollectionRef, fromDocRef, fromRef, sortedChanges, validateEventsArray };
|
|
571
711
|
//# sourceMappingURL=angular-fire-compat-firestore.mjs.map
|