对单个 Firestore 文档进行实时更新

Have realtime updates for a single Firestore document

有很多关于 firestore 集合获取实时更新的文档和示例。但是,对于那些希望单个文档具有实时更新的人来说,几乎没有。我想在只有 item 将被查看和操作的页面上有一个文档(item),并且对文档的任何更改都将进行实时更新。

这是我的组件,它想使用 item:

import { Component, OnInit } from '@angular/core';
import { ItemsService } from '../shared/items.service';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
  selector: 'app-view-item',
  templateUrl: './view-item.component.html',
  styleUrls: ['./view-item.component.css']
})
export class ViewItem implements OnInit {
  item;
  private sub: any;

  constructor(
    // Service used for Firebase calls
    private itemsService: ItemsService,
    private route: ActivatedRoute,
    private router: Router
  ) {}

  ngOnInit() {
    // Item retrieved from */item/:id url
    this.sub = this.route.params.subscribe(params => {
      this.getItem(params['id']);
    });
  }

  getItem = (id) => {
    this.itemsService.getItem(id).subscribe(res => {
      console.log(res);
      this.item = res;
      console.log(this.item);
    });
  }

以及它用于通话的服务:

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';

@Injectable({
  providedIn: 'root'
})
export class ItemsService {
  constructor(
    private firestore: AngularFirestore
  )

  getItem(id) {
    return this.firestore.collection('items').doc(id).snapshotChanges();
  }
}

我得到的 console.log(this.item) 的日志是 undefined。在控制台中调用this.item returns 一样。我不确定如何进行,希望得到任何指导。在控制台中记录 res returns 一个拜占庭对象。也许这就是我访问 item 的方式,但如果是这样,为什么它没有保存在 this.item 中,我如何访问 item 的值?

snapshotChanges returns 可观察到的动作不是实际值。 您应该使用 action.payload.doc.data():

提取值

因此您的代码应类似于以下示例。

getItem(id) {
  return this.firestore.collection('items').doc(id).snapshotChanges()
    .pipe(
      map(actions => actions.map(a => {
        const data = a.payload.doc.data();
        const id = a.payload.doc.id;
        return { id, ...data };
      })
    );
}

或者您可以使用 valueChangesdoc

getItem(id) {
  return this.firestore.collection('items').doc(id).valueChanges();
}