Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Firestore subscribe() fires twice

I'd like to call a function just once whenever my Firebase document data changes, but chaining a .subscribe() onto my valueChanges() causes the subscription to fire twice every time there's an update.

Basic code without a subscription:

home.component.ts:

constructor(private firestore: AngularFirestore) { }

ngOnInit(): void {
    let docName = this.buildDocName();
    this.plants = this.firestore.collection('officePlants').doc(docName).valueChanges();
}

home.component.html:

<mat-list *ngIf="(plants | async)">
    <mat-list-item>Humidity: {{ (plants | async)?.humidity }}</mat-list-item>
    <mat-list-item>Temperature: {{ (plants | async)?.temperature }}</mat-list-item>
</mat-list>

This code causes the subscription to fire twice:

home.component.ts:

ngOnInit(): void {
    let docName = this.buildDocName();
    this.plants = this.firestore.collection('officePlants').doc(docName).valueChanges()
        .subscribe(data => {
            if (!data)
                return;

            console.log('doc updated...', data);
            // ...
        });
}
like image 351
Ryan Loggerythm Avatar asked Feb 25 '26 07:02

Ryan Loggerythm


1 Answers

It might be actually changing twice and your subscription is doing what it is supposed to. You're just not handling that case. Try either to debounce it or filter it if there was no change.

this.plants = this.firestore.collection('officePlants').doc(docName).valueChanges()
  .pipe(
    debounceTime(500)
    //distinctUntilChanged() // or try this, ignores equal data
   )
  .subscribe(data => { /*...*/});

The second problem can be, that you forgot to unsubscribe and you have two living subscriptions at the same time. You need to get rid of them properly.

ngOnDestory() {
  this.plants.unsubscribe();
}
like image 85
mat.hudak Avatar answered Feb 27 '26 21:02

mat.hudak