Nuxt.jsからCloud Functions for FirebaseのonCallを呼んでみた

開発している積読用の[読書管理サービス](https://tsundoku.site)で一部Functionsで処理している部分がある、
`https.onRequest()`を利用しているが、`https.onCall()`のほうが早いらしい。
ので、アプリのみから使う関数を`https.onCall()`で実装したときの備忘録。

Nuxt.jsからCloud Functions for FirebaseをonCall経由で呼ぶ例。

#### onCallの関数はこんな感じ

`msg`を受け取って、`msg`を返す、echo的な関数の例。  
公式ドキュメントでの説明は[こちら](https://firebase.google.com/docs/functions/callable?hl=ja)。

```javascript
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

exports.echo = functions.https.onCall(async (data, context) => {
  // 引数の取得
  const msg = data.msg;
  
  // 認証情報の取得
  const uid = !!context.auth ? context.auth.uid : "";

  console.info(`uid=${uid}, msg=${msg}`);
  
  // 返り値の返却
  return { msg: msg }
});
```

`context.auth`で認証情報を取得できるので、
**関数を呼べるユーザを制限もできる。**



#### 作ったonCall関数をアプリから呼ぶ

こんな感じ。
こんなファイルを用意しておいて、`await doEcho()`を呼べば、
onCall経由でFunctionsの関数を呼ぶことができる。

```typescript
import * as firebase from "firebase/app";
import "firebase/functions";

// firebaseの初期化。
if (!firebase.apps.length) {
  const config = "...";
  if (config) firebase.initializeApp(config);
}

// functionsのインスタンスを取得
const functions = firebase.functions();


export default async function doEcho(msg:string): Promise<string> {
  // 作った関数のインスタンスを取得
  const func = functions.httpsCallable("echo");

  // 作った関数の実行
  const res = await func({ msg: "なんかのメッセージ" });
  
  // 返り値のmsgを取得&返却
  return res.msg
}
```

#### ローカルPCで実行が大変...

作った関数を開発中のアプリから実行するときは、
`useFunctionsEmulator`を使うと良い感じ。

こうすると、呼び出される関数のローカルPCに変更できる。

```javascript
// functionsのインスタンスを取得
const functions = firebase.functions();
if (process.env.NODE_ENV != "productions") {
  functions.useFunctionsEmulator("http://localhost:5000");
}
```

こんな感じで、`useFunctionsEmulator`を設定した上で、

1. `firebase serve --only functions`でfunctionを立ち上げ
2. `nuxt`でNuxt.jsアプリを立ち上げ

とすると、Nuxt.jsがローカルで立ち上げたFunctionsを参照するようになる。
これで開発するときも安心(*´ω｀*)


# おわりに

アプリで使うだけならonCallがはやくてステキ(*´ω｀*)
[積読ハウマッチ](https://tsundoku.site)は、Nuxt.js+Firebaseで開発してます!

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="25%"/>

もしよかったら、遊んでみてくださいヽ(=´▽`=)ﾉ

要望・感想・アドバイスなどあれば、
公式アカウント([@MemoryLoverz](https://twitter.com/MemoryLoverz))や開発者([@kira_puka](https://twitter.com/kira_puka))まで。


# 参考にしたサイト様
- [Firebase HTTPS callable function を試してみる - Qiita](https://qiita.com/star__hoshi/items/909b583b9e1a596de86a)
- [アプリから関数を呼び出す  |  Firebase](https://firebase.google.com/docs/functions/callable?hl=ja)
- [https.onCall のプロトコルの仕様  |  Firebase](https://firebase.google.com/docs/functions/callable-reference?hl=ja)
- [ローカルでの関数の実行  |  Firebase](https://firebase.google.com/docs/functions/local-emulator?hl=ja)
- [How to test `functions.https.onCall` firebase cloud functions locally? - Stack Overflow](https://stackoverflow.com/questions/50884534/how-to-test-functions-https-oncall-firebase-cloud-functions-locally)
- [Firebase Functionsのhttpsトリガーの関数を特定の人からしかできないように制限したい - a42](https://scrapbox.io/a42/Firebase_Functions%E3%81%AEhttps%E3%83%88%E3%83%AA%E3%82%AC%E3%83%BC%E3%81%AE%E9%96%A2%E6%95%B0%E3%82%92%E7%89%B9%E5%AE%9A%E3%81%AE%E4%BA%BA%E3%81%8B%E3%82%89%E3%81%97%E3%81%8B%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%82%88%E3%81%86%E3%81%AB%E5%88%B6%E9%99%90%E3%81%97%E3%81%9F%E3%81%84)