🦔

Firebaseでの開発に必要な最低限の情報

2023/07/19に公開

これまでの開発でFirebaseの機能である、NoSQLのFirestoreと、APIとして関数を叩けるようにするために使うFirebase Functionを使ってきたので、その情報をまとめました。

Firestoreのデータベース設計はどうするべきか?

結論、うまくコレクションとサブコレクション、またはMapとArrayを使い分けるのが肝だと思います。

また、ドキュメントのIDには、ユニークな数字またはインクリメントした数字、ユーザーのidを使うことが多いです。

すでにまとまっている記事

https://qiita.com/KosukeSaigusa/items/860b5a2a6a02331d07cb
上記の記事でFirestoreの使い方を公式動画の情報をもとにわかりやすく解説してくれています。

要約すると、あるコレクションの下にサブコレクションでさらに情報を紐づけるか、ArrayやMapで情報を紐づけていくと良いというものでした。

しかし、ひとつのドキュメントに情報が多くなってしまうようであれば、それはサブコレクションに保管するのではなく、コレクションとして保管するのもありということでした。

Firebase Functionsの使い方

https://firebase.google.com/docs/functions/http-events?hl=ja&gen=2nd
ここにFunctionsを使って、HTTP経由で自前で開発した関数を呼び出す方法が書かれています。

一般的なGET、POSTなどが使えます。

Firebase Functionsで1つexportしてみる

一個例として、APIとしてHTTP経由で関数を叩く例を見てみましょう。

example.js
import * as functions from "firebase-functions";
export const getProducts = functions.https.onRequest(async (request, response) => {
  response.send("返したいものをここに置く")
})

これでfunction経由でreturnSomethingという関数を呼び出すことができるようになりました。ではどう呼び出すのでしょうか??

Firebase Functionsに関数をデプロイする

まず、firebase deploy --only functionsコマンドをターミナルで実行します。そうすることで以下のようにFunctionsにgetProductsの関数がhttps形式でできています。

あとは、このHTTPsのエンドポイントを叩いてあげれば関数が実行されます。実際はこのHTTPSのURLをフロントから叩いてあげることで、フロントからデータをGETしたりPOSTしたりなどバックエンドのやりとりを行います。

以下はフロントのjsファイルだと思ってください。

front.js
import axios from "axios";
await axios.get("https://us-central1・・・/getProducts");

こんな感じでフロントからAPIを呼び出せます。

Express.jsなどとFunctionsを組み合わせる

現場で開発するとなると、Express.jsなどといったフレームワークを使うことになります。そのような場合は、いちいち関数全部をFunctionsでexportするのではなく、APIのエンドポイントとなるURLを1つだけexportすることで、Firebase Functionsで発行するHTTPSのリンクを少なくできます。

backendWithExpress.js
import * as functions from "firebase-functions";
const express = require("express");
const app = express();
const runtimeOpts = {
  timeoutSeconds: 540,
};
export const api = functions.runWith(runtimeOpts).https.onRequest(app);

まず、上記のようにexpressをバックエンドのファイルで呼び出し、appという変数で扱います。そして、さっきのgetProductsという関数ではfunctionの関数内容をexportしましたが、今回はexpress.js全体をexportします。

また、上記の例だとrunWithという関数にruntimeOptsを渡しています。
https://firebase.google.com/docs/functions/manage-functions?hl=ja&gen=2nd#set_runtime_options

timeoutSecondesでは、タイムアウトの時間を設定できます。最大で9分まで設定可能です。

Express.jsをexportし、APIを作ってみる

では、Express.js全体をexportしたという前提で、APIを作ってみましょう。

backendWithExpress.js
import * as functions from "firebase-functions";
const express = require("express");
const app = express();
const runtimeOpts = {
  timeoutSeconds: 540,
};
export const api = functions.runWith(runtimeOpts).https.onRequest(app);

app.get("/top",  (req, res) => {
  res.send("topページにようこそ");
})

上記の/topのURLはhttps://us-central1・・・/api/topというURLになります。

こんな感じでexpressとfirebase functionsを使うとAPIが作れます。

補足)Express.jsでcorsのミドルウェアを使うには?

https://firebase.google.com/docs/hosting/functions?hl=ja#add_middleware
上記に書いてある通りですが、useを使います。

backendWithExpress.js
import * as functions from "firebase-functions";
const express = require("express");
const app = express();
const cors = require("cors");
app.use(cors)

const runtimeOpts = {
  timeoutSeconds: 540,
};
export const api = functions.runWith(runtimeOpts).https.onRequest(app);

app.get("/top",  (req, res) => {
  res.send("topページにようこそ");
})

app.use(cors)このコードでcorsのミドルウェアをexpress.jsで使うことができるようになりました。

Discussion