kokogento
@kokogento (ここ げんと)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Firebase cloud functionsで.envを追加したらデプロイできなくなった。。Failed to load function definition from source

前提

LINE messaging APIの開発で、typescriptとfirebase cloud functionsを使っています。
そしてLINEのchannelSecretchannelAccessTokenを環境変数にしたくて、こちらを参考に.envファイルを
追加しました。

するとデプロイできなくなりました。。。
どなたか助けてください!

ソース内容

index.ts

import * as functions from "firebase-functions";
import * as line from "@line/bot-sdk";
import * as admin from 'firebase-admin';
admin.initializeApp();
// import { config } from '../.env';

interface Config {
  channelAccessToken: string;
  channelSecret: string;
}


const config: Config = {
  // ここをprocess.envではなく直接値を入れるとデプロイできる
  channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN  as string,
  channelSecret: process.env.CHANNEL_SECRET  as string
};

.env

CHANNEL_ACCESS_TOKEN = 'アクセストークン'
CHANNEL_SECRET = 'チャネルシークレット'

エラー内容

% firebase deploy --only functions

=== Deploying to 'line-bot'...

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

> build
> 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  artifactregistry: ensuring required API artifactregistry.googleapis.com is enabled...
✔  artifactregistry: required API artifactregistry.googleapis.com is enabled
✔  functions: required API cloudbuild.googleapis.com is enabled
✔  functions: required API cloudfunctions.googleapis.com is enabled
i  functions: preparing codebase default for deployment
i  functions: Loaded environment variables from .env.

Error: Failed to load function definition from source: Failed to generate manifest from function source: Error: no channel access token
0

2Answer

勘ですが

const config: Config = {
  // ここをprocess.envではなく直接値を入れるとデプロイできる
  channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN  as string,
  channelSecret: process.env.CHANNEL_SECRET  as string
};

が実行されるタイミングではまだ .env がロードされていないせいだと思います。参考にされたページに

// Responds with "Hello Earth and Humans"
exports.hello = functions.https.onRequest((request, response) => {
  response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});

とあるように、関数の中で process.env を読むようにするといいのでは。

それ以前の話として、 API キーなどの機密性の高い値は .env に入れるべきではありません。以下に書いてあるように Secret Manager で管理してください。

2Like

Comments

  1. @kokogento

    Questioner

    ありがとうございます!!
    そもそもAPI キーなどは`.env`で管理するものではなかったのですね・・・。
    根本からやり方を変えてみようと思います!

「そもそも論としてAPI キーなどの機密性の高い値は.envではなく、 Google Cloud Secret Manager を使うべき」
@uasi さんに教えて頂きました!
根本から正しいやり方ではなかったようなので、公式ドキュメントを参考にやり方を改めたいと思います!

0Like

Your answer might help someone💌