简体   繁体   中英

How to subscribe to a firebase snapshot in Angular?

I'm trying to get realtime updates of my firestore database (v9). I set up a service in Angular where I want to do the onSnapshot call to my database but I have no idea on how to send this snapshot to my component and get realtime updates in the component.

This is my service

import { Injectable } from '@angular/core';
import { doc, getFirestore, onSnapshot } from 'firebase/firestore';

@Injectable({
    providedIn: 'root'
})
export class GameService {
    private db;

    constructor() {
        this.db = getFirestore();
    }

    async getGame(code: string) {
        const gameDoc = doc(this.db, 'games', code);
        return onSnapshot(gameDoc, (res) => res.data());
    }
}

This is my component:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { GameService } from 'src/services/game.service';

@Component({
    selector: 'app-game',
    templateUrl: './game.component.html',
    styleUrls: ['./game.component.css']
})
export class GameComponent implements OnInit {
    game: any;

    constructor(private _activatedRoute: ActivatedRoute, private _gameService: GameService) { 
        this.getGame();
    }

    ngOnInit(): void {}

    async getGame() {
        this._activatedRoute.params.subscribe(async (parameters) => {
            let gamecode = parameters['code'];
            let snapshot = this._gameService.getGame(gamecode).then(res => {
                console.log(res.data());
            });
        })
    }
}

I have tried multiple things sending the data from the service to my component but nothing seems to work. Any ideas on how to do this? Thank you very much

You can create an Observable (or other similar structure) to do that. I recommend creating a BehaviorSubject from RXJS. You can create a property in your service like:

public message$: BehaviorSubject<any> = new BehaviorSubject(null);

And you use it inside your "onSnapshot" to send incoming data through the message$ property, like this:

async getGame(code: string) {
    const gameDoc = doc(this.db, 'games', code);
    onSnapshot(gameDoc, (res) => this.message$.next(res.data()));
}

With this you are already transmiting data as it comes to your snapshot, now you only need to access this observable in your component to receive the data you want. So in your component you can do like this:

private subject = new Subject<void>();
ngOnDestroy() {
  this.subject.next();
  this.subject.complete();
}
async getGame() {
    this._activatedRoute.params.subscribe(async (parameters) => {
        let gamecode = parameters['code'];
        this._gameService.getGame(gamecode);
        this._gameService.message$.pipe(takeUntil(this.subject))
         .subscribe((newData) => {
           // YOUR NEW DATA
         });    
    });
}

Please note that the pipe "takeUntil" is from RXJS and is for performance reasons, to ensure that your observable is destroyed when your component is destroyed (avoid memory leak).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM