LoginSignup
175
129

More than 3 years have passed since last update.

CloudFunctionsをきれいに整理したい。

Last updated at Posted at 2019-12-03

こんばんは、Stamp Inc村本です。

普段はFirebaseの技術コンサルティングをやってます。
今日は、Firebase Meetup #15 Cloud Functions Dayが行われてると言うことで、僕は仕事で参加できなかったんだけどちょっとしたTipsを紹介します。

CloudFunctionsの管理って大変ですよね?みんなindex.tsにベタ書きしてたりしませんか?

CloudFunctionsのFunctionを整理する

Functionはネスト可能

CloudFunctionsはJSのモジュールを使えば結構きれいに整理することができます。
CloudFunctionsではネストしたFunctionも認識してくれます。次の例をみてください。

これはシンプルなCallable functionの例です。

index.ts
export const v1 = {
  func: functions.https.onCall((data, context) => {
    // do something
  })
}

これをデプロイした時、クライアントから次のように呼び出すことが可能です。
注目すべきはv1-func

functions.httpsCallable("v1-func").call { (result, error) in
  // do something
}

CloudFunctionsではネストされたFunctionは-でつなげられられます。

Functionはモジュール化可能

次にモジュール化したFunctionを見てみましょう。

v1/index.ts
export const func = functions.https.onCall((data, context) => {
    // do something
})
index.ts
import * as V1 from './v1'
export const v1 = { ...V1 }

これも先ほどと同じようにv1-funcで呼び出すことができます。

CloudFunctionsの構造化

モジュール化できる性質を利用すれば、次のようにファイルを整理することができます。

CloudFirestore TriggerのFunctionをまとめる。

functions
├── index.ts
└── v1 // version管理
    ├── firestore // firestore triggerをまとめる
    │   ├── index.ts
    │   ├── item.ts // itemのtriggerを定義
    │   └── user.ts // userのtriggerを定義
    ├── callable // callableをまとめる
    └── index.ts

まずは/functions/v1/firestore/user.tsから見ていきましょう。
ここではonCreate onUpdate onDeleteを定義しました。

functions/v1/firestore/user.ts
import * as functions from 'firebase-functions'

export const onCreate = functions.firestore
    .document('/versions/{version}/users/{userID}')
    .onCreate(async (snapshot, context) => {
        // do anything
    })

export const onUpdate = functions.firestore
    .document('/versions/{version}/users/{userID}')
    .onUpdate(async (snapshot, context) => {
        // do anything
    })

export const onDelete = functions.firestore
    .document('/versions/{version}/users/{userID}')
    .onDelete(async (snapshot, context) => {
        // do anything
    })

次に、/functions/v1/firestore/index.ts

functions/v1/firestore/index.ts
import * as User from './user'
import * as Item from './item'
export const user = { ...User }
export const item = { ...Item }

この階層では、各々のCollectionに対してファイルを分離することでFunctionの名前を統一化できます。

次に、/functions/v1/index.ts

functions/v1/index.ts
import * as Firestore from './firestore'
export const firestore = { ...Firestore } // Trigger系はここに
export const callable = { ...Callable } // Callable系はここに

最後に、/functions/index.ts

functions/v1/index.ts
import * as V1 from './v1'
export const v1 = { ...V1 }

全てをv1として出力すれば完成!
これで次のようにデプロイされるようになります。

functions
v1-firestore-user-onCreate
v1-firestore-user-onUpdate
v1-firestore-user-onDelete
v1-firestore-item-onCreate
v1-firestore-item-onUpdate
v1-firestore-item-onDelete
v1-callable-...

ここでは定義していませんが、こんな感じでCallableに関しても階層を作ってあげると管理しやすいと思います!

version管理してなくて、index.tsが悲惨になることってあると思います。🤫

デプロイ

ファイル分割の方法を使えばデプロイも楽になります。

全てのfunctionsをデプロイする

firebase deploy --only functions

v1全てをデプロイする

firebase deploy --only functions:v1

v1-firestoreをデプロイする

firebase deploy --only functions:v1.firestore

v1-firestore-userをデプロイする

firebase deploy --only functions:v1.firestore.user

ネストした構成をデプロイするときは、-のところを.で表現するとその部分だけをデプロイ可能です。


おすすめの記事

175
129
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
175
129