CloudFunctionsを使ってFirestoreのサブコレクションを削除する

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}"

これで投稿削除時にサブコレクションが削除されるようになった。

参考


Related #firebase

YouTubeの「Firebase Release Notes」プレイリスト

最新のアップデートの概要を把握するのにちょうど良い

Firebase Extensions

Functionsを実装する際の参考になる

Cloud FunctionsでFirebase Authenticationの認証情報を取得する

functions.https.onCallを使用している場合はcontextパラメータを受け取ることができる

Nuxt.jsのservice workerで環境変数を切り替えられるようにする

設定情報をハードコードしたくなかったので、ビルド時にnodeコマンドでファイル生成を行い環境変数を切り替えられるように対応した。

Firebase Hostingのリリース履歴を一括削除する

いつの間にか一括削除機能が追加されていた