CloudFunctionsを使ってFirestoreのサブコレクションを削除する
Firestoreはドキュメントを削除してもサブコレクションは削除されない仕様とのこと。
とはいえドキュメント削除時にサブコレクションを削除したかったので方法を調べてみたところ、Firebase CLIのdeleteコマンドを呼び出せば一括削除が可能らしい。
ということで、onDeleteイベントをトリガーして、特定のドキュメントが削除されたら、そのドキュメントに紐づくサブコレクションを一括削除するCloudFunctionsの関数を作って対応した。
例としてある投稿に紐づくいいねのサブコレクションを一括削除するサンプルを載せておく。
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
if (admin.apps.length === 0) {
admin.initializeApp()
admin.firestore().settings({ timestampsInSnapshots: true })
}
export default functions
.region('asia-northeast1')
.firestore
.document('posts/{post}')
.onDelete(async (snap, context) => {
const deletedDocument = snap.data()
if (!deletedDocument) {
return
}
const postId = context.params.postId
const firebaseTools = require('firebase-tools')
try {
await firebaseTools.firestore
.delete(`posts/${postId}/like_users`, {
project: process.env.GCLOUD_PROJECT,
recursive: true,
yes: true,
token: functions.config().fb.token
})
} catch (err) {
console.error(err)
}
})
GCLOUD_PROJECTはCloudFunction実行時に自動で設定される環境変数だが、tokenの方は各自で生成してfunctions.configに設定する必要がある。
以下を実行してtokenを生成し、
firebase login:ci
ターミナルに表示されたtokenを以下のコマンドでfunctions.configに設定。
firebase functions:config:set fb.token="{Your Token}"
これで投稿削除時にサブコレクションが削除されるようになった。