简体   繁体   English

如何在Angular订阅firebase快照?

[英]How to subscribe to a firebase snapshot in Angular?

I'm trying to get realtime updates of my firestore database (v9).我正在尝试获取我的 firestore 数据库 (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.我在 Angular 中设置了一项服务,我想在其中对我的数据库执行 onSnapshot 调用,但我不知道如何将此快照发送到我的组件并在组件中获取实时更新。

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.您可以创建一个 Observable(或其他类似结构)来执行此操作。 I recommend creating a BehaviorSubject from RXJS. You can create a property in your service like:我建议从 RXJS 创建一个 BehaviorSubject。您可以在您的服务中创建一个属性,例如:

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

And you use it inside your "onSnapshot" to send incoming data through the message$ property, like this:您在“onSnapshot”中使用它通过 message$ 属性发送传入数据,如下所示:

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).请注意 pipe “takeUntil” 来自 RXJS 并且是出于性能原因,以确保当您的组件被销毁时您的 observable 也被销毁(避免 memory 泄漏)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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