Playground

Firebase の Cloud Functions を typescript で書く

Playground
この記事は約17分で読めます。
スポンサーリンク

お久しぶりです。みやかわです。

今回は Firebase の話です。

私はバックエンドはFirebaseのCloud Function にまかせています。

理由はフロントガシガシ書いたあとにRails等を使ってガシガシ書くのは流石に辛いです。

また、サーバーも調達するのもめんどいためです。

情報が古くて申し訳ないですが、Cloud Function が Typescriptでかけるようになったようなのでやってみることにしました。

セットアップからデプロイするまでの一連をメモ程度に書いていきます。

 

今回は以下の公式サイトに則ってセットアップからデプロイをしてきました。

Cloud Functions に TypeScript を使用する  |  Firebase Documentation

 

スポンサーリンク

セットアップ

CLIの導入

CLI をインストール
※ npm をインストールしていない場合は ここ でインストールする。
$ npm install -g firebase-tools

Firebase にログイン

Firebaseにログインする。
成功すると Success とでる。
% firebase login
Visit this URL on this device to log in:
ttps://accounts.google.com/o/oauth2/auth?~~~~~~

Waiting for authentication...

✔  Success! Logged in as xxxxxx@gmail.com

Cloud Functionを試してみる

プロジェクトの作成

プロジェクトを作成する。
設定する過程で JavaScriptで書くかTypeScriptで書くか聞かれるので TypeScriptを迷わず選択する。
成功すると complete とでる。
% firebase init firestore

     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

You're about to initialize a Firebase project in this directory:

  /path/to/


=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add, 
but for now we'll just set up a default project.

### Create a new project を選択する。
? Please select an option: (Use arrow keys)
    Use an existing project 
❯ Create a new project 
  Add Firebase to an existing Google Cloud Platform project 
  Don't set up a default project 


## テキトーにProject名を作る
? Please specify a unique project id (warning: cannot be modified afterward) [6-
30 characters]:
hogehoge-app

## typescirpt にする
? What language would you like to use to write Cloud Functions? (Use arrow keys)

   JavaScript 
❯ TypeScript 


## eslint 等々の設定を行う。基本エンターでOK。
? What language would you like to use to write Cloud Functions? TypeScript
? Do you want to use ESLint to catch probable bugs and enforce style? Yes
✔  Wrote functions/package.json
✔  Wrote functions/.eslintrc.js
✔  Wrote functions/tsconfig.json
✔  Wrote functions/tsconfig.dev.json
✔  Wrote functions/src/index.ts
✔  Wrote functions/.gitignore
? Do you want to install dependencies with npm now? Yes


i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...
i  Writing gitignore file to .gitignore...

### 生成完了
✔  Firebase initialization complete!

サンプルを実行してみる

firebase/functions/src/index.ts に記載してるコードのコメントアウトをとって、firebase init firestore を実行したファイルパスでテストサーバーを立ち上げる。
結果、エラーになる。
% npm run serve
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /path/to/firebase/package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/path/to/firebase/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent 

npm ERR! A complete log of this run can be found in:
npm ERR!     /path/to/.npm/_logs/2021-12-24T16_30_21_726Z-debug.log
```

エラー内容みると起動させるファイルパスが違う模様。

正解は、firebase init firestore を実行したファイルパスから functionフォルダに移動したところになる。

.
├── firebase.json
├── functions      <----- つまりここ
│   ├── lib
│   │   ├── index.js
│   │   └── index.js.map
│   ├── node_modules
|   ・
|   ・
|   ・
├── package-lock.json
└── tes

改めて、path/to/functionsnpm run serve を実行してみる。

結果、テストサーバーがたちがることを確認🎉

% npm run serve

> functions@ serve /path/to/firebase/functions
> npm run build && firebase emulators:start --only functions


> functions@ build /path/to/firebase/functions
> tsc

i  emulators: Starting emulators: functions
⚠  functions: The following emulators are not running, calls to these services from the Functions emulator will affect production: auth, firestore, database, hosting, pubsub, storage
⚠  Your requested "node" version "16" doesn't match your global version "12"
i  ui: Emulator UI logging to ui-debug.log
i  functions: Watching "/path/to/firebase/functions" for Cloud Functions...
✔  functions[us-central1-helloWorld]: http function initialized (http://localhost:5001/hogehoge-app/us-central1/helloWorld).

┌─────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! It is now safe to connect your app. │
│ i  View Emulator UI at http://localhost:4000                │
└─────────────────────────────────────────────────────────────┘

┌───────────┬────────────────┬─────────────────────────────────┐
│ Emulator  │ Host:Port      │ View in Emulator UI             │
├───────────┼────────────────┼─────────────────────────────────┤
│ Functions │ localhost:5001 │ http://localhost:4000/functions │
└───────────┴────────────────┴─────────────────────────────────┘
  Emulator Hub running at localhost:4400
  Other reserved ports: 4500

Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.

実際にサーバーが立っているか確認してみる。

以下をアクセスすると、ハローワールド表示されるらしい
http://localhost:5001/hogehoge-app/us-central1/helloWorld
アクセスしてみた結果、無事に表示されることを確認。
※ これはあくまでテストサーバーが立っているだけ。Firebaseへのデプロイは後述。

せっかくなので api をひとつ増やす

firebase/functions/src/index.tshoge を追加する。
export const helloWorld = functions.https.onRequest((request, response) => {
  functions.logger.info("Hello logs!", {structuredData: true});
  response.send("Hello from Firebase!");
});

+ export const hoge = functions.https.onRequest((request, response)=>{
+   response.send("hoge!");
+ });
npm run serve を再実行して、以下のURLをリクエスト。
http://localhost:5001/hogehoge-app/us-central1/hoge
狙い通り ‘hoge!’が出力された。

Firebaseにデプロイしてみる

せっかくなので Fireabse にもデプロイしてみる。

デプロイコマンドを実行してみたが、プランのアップデートをしろというエラーが出力される。
 firebase deploy

=== Deploying to 'hogehoge-app'...

i  deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint

> functions@ lint /path/to/hogehoge-app/firebase/functions
> eslint --ext .js,.ts .

Running command: npm --prefix "$RESOURCE_DIR" run build

> functions@ build /path/to/hogehoge-app/firebase/functions
> tsc

✔  functions: Finished running predeploy script.
i  functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i  functions: ensuring required API cloudbuild.googleapis.com is enabled...
i  functions: ensuring required API artifactregistry.googleapis.com is enabled...
⚠  functions: missing required API artifactregistry.googleapis.com. Enabling now...
✔  functions: required API cloudfunctions.googleapis.com is enabled
⚠  functions: missing required API cloudbuild.googleapis.com. Enabling now...

Error: Your project top-hash-tag-server must be on the Blaze (pay-as-you-go) plan to complete this command. Required API cloudbuild.googleapis.com can't be enabled until the upgrade is complete. To upgrade, visit the following URL:

ttps://console.firebase.google.com/project/hogehoge-app/usage/details

Having trouble? Try firebase [command] --help

仕方ないので、コンソールで従量課金プランにアップデートする。

※ 従量課金プランだが、無料枠がかなり大きいのでテストと個人利用程度なら無料で利用できる。

アップデートをしたあとに、再度デプロイをしてみる。

無事に、デプロイできたことを確認。

% firebase deploy

=== Deploying to 'hogehoge-app'...

i  deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint

> functions@ lint /path/to/hogehoge-app/firebase/functions
> eslint --ext .js,.ts .

Running command: npm --prefix "$RESOURCE_DIR" run build

> functions@ build /path/to/hogehoge-app/firebase/functions
> tsc

✔  functions: Finished running predeploy script.
i  functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i  functions: ensuring required API cloudbuild.googleapis.com is enabled...
i  functions: ensuring required API artifactregistry.googleapis.com is enabled...
✔  functions: required API cloudfunctions.googleapis.com is enabled
⚠  functions: missing required API cloudbuild.googleapis.com. Enabling now...
⚠  functions: missing required API artifactregistry.googleapis.com. Enabling now...
✔  functions: required API cloudbuild.googleapis.com is enabled
✔  functions: required API artifactregistry.googleapis.com is enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (44.62 KB) for uploading
✔  functions: functions folder uploaded successfully
i  functions: creating Node.js 16 function helloWorld(us-central1)...
i  functions: creating Node.js 16 function hoge(us-central1)...

✔  functions[hoge(us-central1)] Successful create operation.
✔  functions[helloWorld(us-central1)] Successful create operation.
Function URL (helloWorld(us-central1)): https://fire-base-deply-url/helloWorld
Function URL (hoge(us-central1)): https://fire-base-deply-url/hoge
i  functions: cleaning up build files...

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/hogehoge-app/overview

コンソール画面でもデプロイできたことを確認。

せっかくなのでリクエストしてみると、ちゃんとレスポンスが返ってくることを確認。

まとめ

Firebase の Cloud Functions を typescript で書く方法をメモ程度にまとめました。

(まとめたといってもサンプルをなぞっただけですが・・・)

流れ的には firebase/functions/src/index.tsexport const ${path} という感じで書いていけば勝手にパスができるようです。
firebase/functions/src/index.ts を起点に色々書いていけば良さそう。
とりあえず、これで型がある安全なJavaScriptを書くことができます。

コメント

タイトルとURLをコピーしました