[JS] Firebaseの覚書 ⑥ FunctionsでAPI作成

Firebaseの覚え書きには番号つけてますが内容はつながってません。
この記事はAuthenticationは使ってません。

以下、ほぼほぼリファレンス通りの内容になってます。

# インストール(npmでもいい)
yarn global add firebase-tools

# ログインを試す
firebase login

# プロジェクトの一覧を表示してみる
firebase projects:list

# ログアウト
firebase logout

これでプロジェクトのリストが取得できないとかいうエラーが出た場合は、ログアウトしてからもう一度ログインしてみる。
(アプリ連携が未認証で失敗している可能性が高い)

以下進める前に、nvmでnode.jsのバージョンを 10.10.0 にしておく。

Firebase init

適当なディレクトリ作成して移動したら初期化コマンド実行。

firebase init

質問に従って選択していく。

? Which Firebase CLI features do you want to set up for this folder? Press Space
to select features, then Enter to confirm your choices. (Press to selec
t, to toggle all, to invert selection)
❯◯ Database: Deploy Firebase Realtime Database Rules
◯ Firestore: Deploy rules and create indexes for Firestore
◯ Functions: Configure and deploy Cloud Functions
◯ Hosting: Configure and deploy Firebase Hosting sites
◯ Storage: Deploy Cloud Storage security rules
◯ Emulators: Set up local emulators for Firebase features

firebase init

FunctionsとEmulatorsを選択。それとFirestore。
Firestoreは先にコンソールでデータベース作成できる状態まで開放してないとエラーになる。

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.?
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

firebase init

プロジェクトどうするかという質問。
一番上を選択した場合は作成済みのプロジェクトリストが表示されて選択できる。(コマンド projects:list が失敗するとこれも失敗する)

Firestore Security Rules allow you to define how and when to allow
requests. You can keep these rules in your project directory
and publish them with firebase deploy.

? What file should be used for Firestore Rules?

firebase init

デフォルトの firestore.rules でおk。

Firestore indexes allow you to perform complex queries while
maintaining performance that scales with the size of the result
set. You can keep index definitions in your project directory
and publish them with firebase deploy.

? What file should be used for Firestore indexes?

firebase ini

これもデフォルトのfirestore.indexes.jsonでおk。

A functions directory will be created in your project with a Node.js
package pre-configured. Functions can be deployed with firebase deploy.

? What language would you like to use to write Cloud Functions? (Use arrow keys)

❯ JavaScript
TypeScript

firebase init

TypeScriptも対応してますよ、と。

?Do you want to use ESLint to catch probable bugs and enforce style? (y/N)

firebase init

ESlintは使ったほうがいいですね。

? Do you want to install dependencies with npm now? (Y/n)

firebase init

Yでおk。

? Which Firebase emulators do you want to set up? Press Space to select emulator
s, then Enter to confirm your choices. (Press to select, to toggle a
ll, to invert selection)
❯◯ Functions
◯ Firestore
◯ Database
◯ Hosting
◯ Pubsub

firebase init

なにをエミュるかの選択。FunctionsとFirestoreかな…。

? Which port do you want to use for the functions emulator? (5001)

firebase init

? Which port do you want to use for the firestore emulator? (8080)

firebase init

他と喧嘩するようなら変えとこう。

? Would you like to download the emulators now? (y/N)

firebase init

今ダウンロードしていいですね。

このような質問に全部答えたらいろいろなファイルが生成されたディレクトリが出来上がる。

Functions 関数の記述とデプロイ

functionsディレクトリの中にindex.jsファイルが出来てるんで適当なエディタでそれを開く。
最初の1行目だけ残して、あとのコメントは消す。

で、onCall版のHello Worldを書きまして…

const functions = require('firebase-functions');

exports.helloWorld = functions.https.onCall((data, context) => {
  return {
    message: "Hello from Functions!",
  };
});

terminalでデプロイコマンドを叩きます

 firebase deploy --only functions:helloWorld

しばらく待つとデプロイ終わる。
コンソールでFunctionsに追加されているのが確認できる。

クライアントからFunctionsの関数を呼び出す

既存のfirebaseクライアントに追加するとします。
以下は CodesandboxにあるNuxt.jsのデモアプリでやってます。

firebaseのアプリ設定のところでfunctions追加して、ビルドして

import * as firebase from "firebase/app";

import "firebase/functions";

これはVueだけど、ボタンかなんかに適当なイベントハンドラ追加して

<button class="button--green" type="button" @click.prevent="onHelloWorld">HelloWorld</button>

そのイベントハンドラでhelloWorldを呼びますれば

onHelloWorld() {
  firebase.functions().httpsCallable('helloWorld')()
  .then((result) => {
    console.log(result)
  })
}

キマシタワー!

functionsのチュートリアルだとonRequestの例しか書いてないんだけど、onRequestだとCORSでめっちゃ怒られるので面倒くさい。
onCallを呼び出すこの方法だと面倒な手続きは全部JavaScript SDKがやってくれるし、APIのURLを直接ブラウザで開くとBad Requestになる。

このHelloWorldは認証必要なものを一切使ってないんで、どこで叩いてもエラーにはならない。
認証済ユーザーがonCallを実行した場合、SDKがリクエストヘッダにauthorization(JWT)を追加する。

参考

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください