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で特定のfieldがnullのドキュメントを取得する

where('field', '==', null)で条件指定できる

Firebase Functionsのスケジュール実行はローカルでは動かない

まだサポートされておらず機能リクエストがissueに挙がっている状況

SharedArrayBuffer updates in Android Chrome 88 and Desktop Chrome 92

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

_this.auth.addAuthTokenListener is not a function

8.6.5にダウングレードした

Firebase Auth Googleログイン時のリダイレクトドメインを変更する

CNAME追加とHostingの「カスタムドメインを追加」を行う