簡體   English   中英

從 Firestore 查詢數據作為可觀察的

[英]Querying data from Firestore as observable

我正在使用此請求從 Firestore 異步獲取我的文檔。

在操作(例如刪除)期間,我的文檔列表不會自動更新。 如何將我的異步 function 轉換為可觀察對象,以便利用 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 的可觀察對象,你需要在 AngularFirestoreCollection 上返回 the.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() 中返回),則需要使用snapshotChanges() 有時在保存到 Firestore 時維護用戶數據的 ID 會更容易,以避免使用 snapshotChanges。 SwitchMap在這種情況下也很有用,因為當新值來自源(在本例中為 userId)時,它將取消其先前的 firestore 訂閱並切換到具有新用戶 ID 的新訂閱。 如果出於某種原因,您希望為一次通過的所有 userId 維護 firestore 訂閱,請改用 mergeMap。 但通常您一次只想訂閱一個用戶的數據。

// 通過特定的 email 查詢用戶並返回使用 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; 
} 
}));

訂閱更改的注意事項:

用戶將是 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 中使用異步 pipe 來處理訂閱和取消訂閱,如下所示:

<div *ngIf="(user$ | async) as user">{{ user.email }}</div>

盡量避免在您的 html 中多次對同一可觀察對象使用異步 pipe,而是將其設置為本地 html 變量,我在上面(作為用戶)這樣做以避免不必要的數據訪問數據庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM