-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(afs): Allow multiple subscribers by using share, closes #1191 #1192
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work, @jamesdaniels! Just a few things :)
|
||
const changes = stocks.valueChanges(); | ||
|
||
const subA = changes.subscribe(data => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nest these subscriptions to test that one happens after another. I did this locally:
it('should handle multiple subscriptions', async (done) => {
const ITEMS = 4;
const { randomCollectionName, ref, stocks, names } = await collectionHarness(afs, ITEMS);
const obs = stocks.valueChanges();
const sub1 = obs.subscribe(values1 => {
const sub2 = obs.subscribe(values2 => {
expect(values1.length).toEqual(values2.length);
deleteThemAll(names, ref).then(done).catch(done.fail);
});
});
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah good point.
@@ -89,7 +90,7 @@ export class AngularFirestoreCollection<T> { | |||
*/ | |||
snapshotChanges(events?: firebase.firestore.DocumentChangeType[]): Observable<DocumentChangeAction[]> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need the .share()
operator further down in fromRef.ts
. That way each observable method benefits from a "shared" source.
export function fromRef<R>(ref: firebase.firestore.DocumentReference | firebase.firestore.Query) {
return _fromRef<typeof ref, R>(ref).share();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM, but as a optimization.
As mentioned, we need the share on sortedChanges
(which I'll bump up to the definition) to make the side effects (combineChanges
) occur only the once.
@davideast found a couple more hairy problems here, spent the evening hacking work arounds together but couldn't find anything more elegant then firing |
src/firestore/collection/changes.ts
Outdated
@@ -28,7 +29,8 @@ export function sortedChanges(query: firebase.firestore.Query, events: firebase. | |||
return fromCollectionRef(query) | |||
.map(changes => changes.payload.docChanges) | |||
.scan((current, changes) => combineChanges(current, changes, events), []) | |||
.map(changes => changes.map(c => ({ type: c.type, payload: c }))); | |||
.map(changes => changes.map(c => ({ type: c.type, payload: c }))) | |||
.shareReplay(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need .share()
since .shareReplay()
caches the data.
Ok I found the troubles, another commit coming in shortly. |
Checklist
npm install
,npm run build
, andnpm test
run successfully? yesDescription
Subscribing to AFS collection multiple times causes duplicate data to show up. This is due to events replaying in
fromRef#combineChange
.Adding
share()
tocollection#snapshotChange
fixes this issue as the side-effects will only occur the once.