如何在Angular中订阅firebase快照?

6kkfgxo0  于 2023-01-14  发布在  Angular
关注(0)|答案(1)|浏览(111)

我正在尝试获取firestore数据库(v9)的实时更新。我在Angular中设置了一个服务,我想在其中对我的数据库进行onSnapshot调用,但我不知道如何将此快照发送到我的组件并在组件中获取实时更新。
这是我的服务

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());
    }
}

这是我的组件:

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());
            });
        })
    }
}

我已经尝试了多种方法将数据从服务发送到我的组件,但似乎都不起作用。有什么想法如何做到这一点吗?非常感谢

kgqe7b3p

kgqe7b3p1#

你可以创建一个Observable(或其他类似的结构)来实现这一点。我建议从RXJS创建一个BehaviorSubject。你可以在你的服务中创建一个属性,比如:

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

您可以在“onSnapshot”中使用它通过message$属性发送传入数据,如下所示:

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

这样你就可以在快照中传输数据了,现在你只需要在你的组件中访问这个可观察对象就可以接收你想要的数据了,所以在你的组件中你可以这样做:

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
         });    
    });
}

请注意,管道“takeUntil”来自RXJS,并且是出于性能原因,以确保在销毁组件时销毁可观察对象(避免内存泄漏)。

相关问题