firebase 如何将Firestore collectionGroup数据作为Angular 观测值?

beq87vna  于 2023-01-27  发布在  Angular
关注(0)|答案(2)|浏览(120)

https://firebase.google.com/docs/firestore/query-data/queries文档片段中,我无法获得作为Observable的结果

import { collectionGroup, query, where, getDocs } from "firebase/firestore";  

const museums = query(collectionGroup(db, 'landmarks'), where('type', '==', 'museum'));
const querySnapshot = await getDocs(museums);
querySnapshot.forEach((doc) => {
    console.log(doc.id, ' => ', doc.data());
});

所以我这样写:

const museums = query(
  collectionGroup(db, 'landmarks'),
  where('type', '==', 'museum')
);
const querySnapshot = await getDocs(museums);
const datas = querySnapshot.docs.map((doc) => {
  return doc.data() as Data;
});
console.log(datas);
return of(datas);

但是当订阅它或在DOM中使用异步管道时,我没有得到结果,但是当我使用console.log()时,有一个数据数组。
component.html

{{ museums_data$ | async }}

component.ts

this.museums_data$.subscribe((datas) => console.log(datas));
4c8rllxm

4c8rllxm1#

我在这里找到的:https://code.build/p/LWmSi3HfQzu5TMKPzb5p6i/angular-12-with-firebase-9,这是为集合编写的,假设它也应该对集合组起作用,我试了一下,它的表现和预期的一样。
这是在链接中找到的代码片段:

collectionData<Post>(
      query<Post>(
        collection(this.afs, 'posts') as CollectionReference<Post>,
        where('published', '==', true)
      ), { idField: 'id' }
    );

致:

collectionData<Landmark>(
      query<Landmark>(
        collectionGroup(db, 'landmarks') as CollectionReference<Landmark>,
        where('type', '==', 'museum')
      ), { idField: 'id' }
    );
mftmpeh8

mftmpeh82#

乍一看,代码看起来不错,但是返回的代码不正确。您可以直接使用as Observable<Data[]>返回代码,而不是Map。虽然我没有考虑错误处理,但使用catchError rxjs操作符可以很容易地实现这一点。
您可以使用以下技术通过async管道获取所需的数据。

数据.服务.ts

import { Injectable } from '@angular/core';
import { collection, collectionData, Firestore, query, where
} from '@angular/fire/firestore';
import { Observable } from 'rxjs';
import { Data } from './data;

@Injectable({
  providedIn: 'root',
})
export class DataService {
constructor(private db: Firestore) {}
  getData(): Observable<Data[]> {
    const ref = collection(this.db, 'landmarks);
    const q = query(ref, where(type, '==', museum));
    const data = collectionData(q, {
      idField: 'id',
    });
    return data as Observable<Data[]>;
  }

并在相应的组件中这样使用它:

应用程序组件.ts

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { DataService } from './data.service';
import { Data } from './data;

@Component({
  selector: 'app-root',
  template: `
<div *ngFor="let museum of museums_data$ | async">
{{ museum.id }} // …
</div> `,
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  museums_data$!: Observable<Data[]>;
  constructor(private service: DataService) {}
  ngOnInit(): void {
    this.museums_data$ = this.service.getData();
  }
}

要了解更多信息,可以使用this article进行很好的解释。

相关问题