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

SharedArrayBuffer updates in Android Chrome 88 and Desktop Chrome 92

クロスオリジン分離対応を実施

Firebase Emulator Suiteで起動しているFunctionsから本番のFirestoreにアクセスする

functionsのみエミュレータを使うようにするとできる

Firebase Functions呼び出し時に Error: function terminated. が発生した場合

firebase functions:logで詳細を確認できる

Cloud BuildでFirebase Hostingのデプロイを行う

リポジトリへのpush以外をトリガーにしたい場合に使用

Firebase FunctionsでonCallで実装しているにも関わらずCORSエラーが発生した場合

Cloud Functions(GCP)の管理画面を確認してみる

JestでFirestoreセキュリティルールのテストを書く

Github ActionsでCIを回せるようになった