23
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Google Cloud Schduler API】 Firebase functionsで使ってみた

Last updated at Posted at 2019-10-25

きっかけ

大学の研究で進化計算というものを行っており、進化の処理を行うために利用しました。

本記事では、firebaseプロジェクトの作成、functionsの設定まで済んでいるというところをスタート地点として説明していきます。

自動でタスクを実行する流れ

今回は、firestoreにドキュメントが作成されたら、その情報を元にスケジュールを作成するサンプルを作成します。
流れとしては、

  1. 定期的に実行したいfunctions.pubsubを作成
  2. スケジュールの作成、削除
  3. functions.onCreateでスケジュールの作成、削除を発火

pub/subを利用する理由として、httpsだと誰からでも起動できてしまうため、セキュリティ的なデメリットがあるからです。
また、スケジューラと紐付ける時に相性がいいです。

では、順を追って説明していきます。

pubsubの作成

今回のサンプルではスケジューラで送られてきたメッセージをログに表示していきます。

const locationId = "asia-northeast1"; // region
const projectId = "scheduler-api-sample"; // firebaseのプロジェクト名
const topicName = "sample-pubsub"; // pub/subの名前
const jobName = "sample-job"; // スケジューラのジョブの名前

...

exports.samplePubSub = functions.pubsub
  .region(locationId)
  .pubsub.topic(topicName)
  .onPublish(message => {
    const messageBody = message.data ? message.data : null
    console.log("messageBody:", message.data)
  })

...

スケジュールの作成、削除

モジュールの追加

yarn add @google-cloud/scheduler
でモジュールを追加します。

注意点として、プロジェクト/package.jsonでなくプロジェクト/functions/package.jsonに対して追加してください。

初期化

const scheduler = require("@google-cloud/scheduler");

const client = new scheduler.v1beta1.CloudSchedulerClient({ projectId });

projectIdを渡して、どのプロジェクトに対してジョブを追加するか予め設定しておきます。

ジョブの作成


const formattedParent = client.locationPath(projectId, locationId);
const formattedJobName = client.jobPath(projectId, locationId, termDocId);

const registerJob = () => {
  
  const interval = `0 0 * * *`; // crontab or App Engine Cron

  const req = {
    parent: formattedParent,
    job: {
      name: formattedJobName,
      schedule: interval,
      pubsubTarget: {
        topicName: `projects/${projectId}/topics/${topicName}`,
        data: Buffer.from('published').toString("base64")
      }
    }
  };

  client
    .createJob(req)
    .then(res => console.log(res[0]))
    .catch(e => console.error(e));
}

formattedParent => projects/[PROJECT_ID]/locations/[LOCATION_ID]
formattedJobName => projects/[PROJECT_ID]/locations/[LOCATION_ID]/jobs/[JOB_ID]
を生成してくれます。

パラメータについては公式サイトに詳しく載っていますので、もっと知りたい方は以下のリンクを参考にしてください。
登録済みのジョブのリストや更新などについても載っています。

公式サイト
https://cloud.google.com/nodejs/docs/reference/scheduler/0.1.x/google.cloud.scheduler.v1beta1?hl=ja#.Job

ジョブの削除

const unRegisterJob = () => {
  const req = {
    name: formattedJobName
  };

  client.deleteJob(req).catch(e => console.error(e));
};

こちらはジョブの名前を指定するだけで削除ができます。

functionsで追加する

exports.sampleFirestoreOnCreate = functions
  .region(locationId)
  .firestore
  .document("samples/{docId}")
  .onCreate((snap, context) => {
    registerJob();
  }

これでsamplesコレクションにドキュメントが作成されたらジョブが設定されるようになりました!
0 0 * * *間隔に設定しているので、毎日0時0分になったらpublishTarget.dataで渡したメッセージ(published)をログで出力します。

いろいろ試していて、ジョブの名前が重複していると登録ができなかったので、自動で追加する場合にはfirestoreで自動生成されるドキュメントIDなどを使うといいかもです。
僕はdocIdregisterJobに渡してjobIdとして登録することで重複を避けました。

所感

schedulerのAPI利用については記事があまり無いのでこのモジュールにたどり着くまで結構時間がかかりました。もっとGCPを使いこなしたいですね。

みなさんよいfirebaseライフを!

※ 間違いや動かないぞ!ということがありましたらコメントにお願いします。

23
9
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
23
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?