[Firebase] Cloud FunctionsでFirestoreのドキュメントとサブコレクションをまとめて削除する方法
はじめに
Firestoreはドキュメントを削除してもドキュメント配下にあるサブコレクションは残ってしまいます。
ドキュメントを削除するときにサブコレクションのドキュメントも一つずつ削除していけば良いですが、サブコレクションが増えてきたらかなり面倒。
ドキュメント削除したときには以下にあるサブコレクションもまとめて削除する方法を調べていたところ、Firebase CLIのfirestore:delete
コマンドを利用することで一括で削除できると書いてありました。firebase-tools
を使うことでFirebase CLIの関数を使えます。
公式ではこの方法を推奨しているようです。
なので、Cloud Functionsのドキュメント削除(onDelete)をトリガーにして、ドキュメント配下のサブコレクションも一括で削除する方法を紹介します。
(Cloud FunctionsはTypescriptで書いています)
firebase-toolsをインストール
まずはfirebase-toolsをfunctionsディレクトリにインストールしましょう!
$ npm install firebase-tools
↓のような感じでfunctions/package.jsonに追加されていると思います。
{
"name": "functions",
...
"dependencies": {
"firebase-admin": "^8.10.0",
"firebase-functions": "^3.6.1",
+ "firebase-tools": "^9.20.0"
},
...
}
環境変数にトークンを設定
firebaseにログイン認証してトークンを取得します。
$ firebase login:ci
Visit this URL on this device to log in:
[ここに表示されるURLに飛んでログイン]
Waiting for authentication...
✔ Success! Use this token to login on a CI server:
# ここにトークンが表示されるのでコピーしておいてください
**********
Example: firebase deploy --token "$FIREBASE_TOKEN"
次にコピーしたトークンを環境変数に設定します。
$ firebase functions:config:set fb.token="さっきコピーしたトークン"
✔ Functions config updated.
Please deploy your functions for the change to take effect by running firebase deploy --only functions
Cloud Functionに処理を追加
usersコレクション内のドキュメント削除をトリガーにドキュメント配下のサブコレクションを全て削除する処理を追加していきます。
使用する環境変数の
process.env.GCLOUD_PROJECT
はプロジェクト作成時に自動で設定されているものなので、そのまま使えます。
functions.config().fb.token
はさっき設定したトークンが入っています。
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
// firebase_toolsをインポート
const firebase_tools = require('firebase-tools')
admin.initializeApp(functions.config().firebase)
export const onDelete = functions
.region('asia-northeast1')
.firestore
.document('users/{uid}')
.onDelete(async (snapshot, context) => {
// 環境変数の確認用
console.log(process.env.GCLOUD_PROJECT)
console.log(functions.config().fb.token)
try {
// 削除されたドキュメントのパスを取得
const path = snapshot.ref.path
await firebase_tools.firestore
.delete(path, {
project: process.env.GCLOUD_PROJECT,
recursive: true,
yes: true,
token: functions.config().fb.token
})
} catch (error) {
console.log(error)
throw error
}
})
これでユーザードキュメント削除時にサブコレクションを一括で削除されるようになりました。
参考
Discussion