从 Firestore 查询数据作为可观察的
Quering data from Firestore as observable
我正在使用此请求从 Firestore 异步获取我的文档。
在操作(例如删除)期间,我的文档列表不会自动更新。如何将我的异步函数转换为可观察函数,以便利用 Firestore 的实时功能并获取文档的 ID?
import { Injectable } from '@angular/core';
import { SentencePair } from '../models/sentence-pair.model';
import { Firestore, collectionData, deleteDoc,limit, limitToLast,orderBy, increment,
addDoc, collection, doc, updateDoc, setDoc,query, where, getDocs } from
'@angular/fire/firestore';
import { Observable,combineLatest,map, defer } from 'rxjs';
@Injectable({ providedIn: 'root'})
export class SentencesPairsService {
constructor(private firestore: Firestore) { }
async FilterPairs(field: string, boolean: boolean, display:any) {
const sentencepairsRef = collection(this.firestore, 'SentencesPairs');
const q = query(sentencepairsRef,
where('validation', '==', boolean),
where('origin_trad', 'in', display),
orderBy(field),limitToLast(10));
const truc = await getDocs(q)
return truc.docs.map(docData=>({...docData.data(), id:docData.id}));
}
我使用 AngularFire 7.2。感谢您的帮助。
从 Firestore 查询中获取数据的可观察对象
如果您想要来自 Firestore 的可观察对象,您需要 return AngularFirestoreCollection 上的 .valueChanges()。阅读此文档以供参考:https://github.com/angular/angularfire2/blob/master/docs/firestore/querying-collections.md.
例如:
getUserByEmail(email: string): Observable<User> {
const collection = this.firestore.collection<User>('users', ref => ref.where('email', '==', email))
const user$ = collection
.valueChanges()
.pipe( map(users => {
const user = users[0];
console.log(user);
return user;
}));
return user$;
}
获取文档的 ID
如果您想要文档中的 ID(未在 valueChanges() 中 return 编辑),则需要使用 snapshotChanges()
。有时在保存到 Firestore 时维护用户数据的 ID 会更容易,以避免使用 snapshotChanges。 SwitchMap
在这种情况下也很有用,因为当新值来自源(在本例中为 userId)时,它将取消其之前的 firestore 订阅并切换到具有新用户 ID 的新订阅。如果出于某种原因,您希望为一次通过的所有 userId 维护 firestore 订阅,请改用 mergeMap。但通常您一次只想订阅一个用户的数据。
// 通过特定的电子邮件查询用户和 return 使用 snapshotChanges() 添加 ID 的第一个用户
return this.firestore.collection<User>('users', ref => ref.where('email', '==', email))
.snapshotChanges()
.pipe(map(users => {
const user = users[0];
if (user) {
const data = user.payload.doc.data() as User;
const id = user.payload.doc.id;
return { id, ...data };
}
else { return null;
}
}));
订阅更改注意事项:
在您在 this.user$ 上调用订阅之前,该用户将为空:
const queryObservable = size$.pipe(
switchMap(size =>
afs.collection('items', ref => ref.where('size', '==', size)).snapshotChanges()
)
);
queryObservable.subscribe(queriedItems => {
console.log(queriedItems);
});
或
在您的 html 中使用处理订阅和取消订阅的异步管道,如下所示:
<div *ngIf="(user$ | async) as user">{{ user.email }}</div>
尽量避免在您的 html 中多次对同一个可观察对象使用异步管道,而是将其设置为我在上面(作为用户)所做的本地 html 变量,以避免不必要的数据库的数据访问。
我正在使用此请求从 Firestore 异步获取我的文档。
在操作(例如删除)期间,我的文档列表不会自动更新。如何将我的异步函数转换为可观察函数,以便利用 Firestore 的实时功能并获取文档的 ID?
import { Injectable } from '@angular/core';
import { SentencePair } from '../models/sentence-pair.model';
import { Firestore, collectionData, deleteDoc,limit, limitToLast,orderBy, increment,
addDoc, collection, doc, updateDoc, setDoc,query, where, getDocs } from
'@angular/fire/firestore';
import { Observable,combineLatest,map, defer } from 'rxjs';
@Injectable({ providedIn: 'root'})
export class SentencesPairsService {
constructor(private firestore: Firestore) { }
async FilterPairs(field: string, boolean: boolean, display:any) {
const sentencepairsRef = collection(this.firestore, 'SentencesPairs');
const q = query(sentencepairsRef,
where('validation', '==', boolean),
where('origin_trad', 'in', display),
orderBy(field),limitToLast(10));
const truc = await getDocs(q)
return truc.docs.map(docData=>({...docData.data(), id:docData.id}));
}
我使用 AngularFire 7.2。感谢您的帮助。
从 Firestore 查询中获取数据的可观察对象
如果您想要来自 Firestore 的可观察对象,您需要 return AngularFirestoreCollection 上的 .valueChanges()。阅读此文档以供参考:https://github.com/angular/angularfire2/blob/master/docs/firestore/querying-collections.md.
例如:
getUserByEmail(email: string): Observable<User> {
const collection = this.firestore.collection<User>('users', ref => ref.where('email', '==', email))
const user$ = collection
.valueChanges()
.pipe( map(users => {
const user = users[0];
console.log(user);
return user;
}));
return user$;
}
获取文档的 ID
如果您想要文档中的 ID(未在 valueChanges() 中 return 编辑),则需要使用 snapshotChanges()
。有时在保存到 Firestore 时维护用户数据的 ID 会更容易,以避免使用 snapshotChanges。 SwitchMap
在这种情况下也很有用,因为当新值来自源(在本例中为 userId)时,它将取消其之前的 firestore 订阅并切换到具有新用户 ID 的新订阅。如果出于某种原因,您希望为一次通过的所有 userId 维护 firestore 订阅,请改用 mergeMap。但通常您一次只想订阅一个用户的数据。
// 通过特定的电子邮件查询用户和 return 使用 snapshotChanges() 添加 ID 的第一个用户
return this.firestore.collection<User>('users', ref => ref.where('email', '==', email))
.snapshotChanges()
.pipe(map(users => {
const user = users[0];
if (user) {
const data = user.payload.doc.data() as User;
const id = user.payload.doc.id;
return { id, ...data };
}
else { return null;
}
}));
订阅更改注意事项:
在您在 this.user$ 上调用订阅之前,该用户将为空:
const queryObservable = size$.pipe(
switchMap(size =>
afs.collection('items', ref => ref.where('size', '==', size)).snapshotChanges()
)
);
queryObservable.subscribe(queriedItems => {
console.log(queriedItems);
});
或
在您的 html 中使用处理订阅和取消订阅的异步管道,如下所示:
<div *ngIf="(user$ | async) as user">{{ user.email }}</div>
尽量避免在您的 html 中多次对同一个可观察对象使用异步管道,而是将其设置为我在上面(作为用户)所做的本地 html 变量,以避免不必要的数据库的数据访问。