#Firestore: 全データ件数を取得する方法
ページネーションで必要な、Firestoreコレクションの全データ件数取得。データサイズによって取得方法を変えた方がよい(パフォーマンスに影響)。
以下に方法。
##数百件程度の場合
データをローカルにロードしてカウントする。
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
constructor(
private db: AngularFirestore,
) {}
ngOnInit() {
}
length: number; // 全件数を格納する変数
// commentsコレクションの全データ件数を獲得しlengthに保存
getDataSize() {
this.db.collection('comments').valueChanges().subscribe( values => {
console.log('■データ数は、' + values.length);
this.length = values.length
})
}
そしてこの関数をngOnInit() {..}に突っ込んでおけばいい。
ngOnInit() {
this.getDataSize();
}
##数千件の場合
Cloud Functionsを利用してそちらでカウントさせる。
Functionsの利用の仕方はこちらで。
#####functions/src/index.tsを編集
コードは以下の通り。
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as rp from 'request-promise';
// firebase の初期化
admin.initializeApp(functions.config().firebase)
const fireStore = admin.firestore()
// commentsコレクションのデータ数カウント
exports.countComments = functions.https.onRequest((req, res) => {
let commentsfaqsRef = fireStore.collection('commentsfaqs');
commentsfaqsRef.get().then( snap => {
res.header('Access-Control-Allow-Origin', "*");
res.header('Access-Control-Allow-Headers', "Origin, X-Requested-With, Content-Type, Accept");
res.status(200).send({length: snap.size});
})
.catch(error => {
res.send( error() );
});
});
res.header('Access-Control-Allow-Origin', "*");
res.header('Access-Control-Allow-Headers', "Origin, X-Requested-With, Content-Type, Accept");
の2行をつけないとCORS関連のエラーがでる。
こんな感じのエラーメッセージ↓
Access to fetch at 'https://<your-project>.cloudfunctions.net/<your-function>'
from origin 'http://localhost:3000' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
If an opaque response serves your needs,
set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
#####firebase deploy
そうしたら該当ファンクションだけデプロイする。
$ firebase deploy --only functions:countComments
以下のようにcountCommentsファンクションだけデプロイされ、完了前にFunction URLが表示されるので控えておく。
…略…
i functions: uploading functions in project: countComments(us-central1)
i functions: creating Node.js 8 function countComments(us-central1)...
+ functions[countComments(us-central1)]: Successful create operation.
Function URL (countComments): https://us-central1-projectName.cloudfunctions.net/countComments
Deploy complete!
ためしにそのURLにアクセスすると、
カウントされたデータ件数が表示されている。
#####クライアント側でRESTクライアントを実装する
あとはcountCommentsが吐き出したデータ件数をクライアント側(Angular)でフェッチするだけ。HttpClientModuleを使う。
- app.module.tsにHttpClientModuleをインポート
import { HttpClientModule } from '@angular/common/http';
imports: [
HttpClientModule,
]
- データ件数を利用したいコンポーネントに関数を作る
import { HttpClient } from '@angular/common/http';
constructor(
private httpClient: HttpClient,
) {}
ngOnInit() {
this.getDataSize();
}
countCommentsURL : string = 'https://us-central1-projectName.cloudfunctions.net/countComments' // function 'countComments'のURL
length: number; // 全件数を格納する変数
// commentsコレクションの全データ件数を獲得しlengthに保存
async getDataSize() {
this.httpClient.get(this.countCommentsURL)
.toPromise()
.then((res) => {
const response: any = res;
this.length = response.length
})
.catch((error) =>
console.log(error)
);
}
##一万件以上の場合
To Be Continue…
参考:
[Angular] HTTPクライアント(RESTクライアント)を実装する
FirebaseのCloud FunctionsでCORSが~とかAccess-Control-Allow-Originが~と言われたらこれ
Google Cloud Functionsでcorsを有効にする