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

Firestoreの複合インデックスを削除する

CLI経由で削除する必要があった

Firebase Web SDK v9

_this.auth.addAuthTokenListener is not a function

8.6.5にダウングレードした

Firebase Summit 2021