firebase deploy --only functions:### がエラーになりFunctionsをデプロイできない

※当サイトは、アフィリエイト広告を利用しています

結論:node.js・Firebase CLI・TypeScriptを更新、try catch文に型判定を導入

2022/11/14 Flutter エラー・バグ日記

 

画像認識ができるCloud Vision APIにアクセスするため、FunctionsのサンプルコードをFirebaseにデプロイすべく、

 

firebase deploy --only functions:(関数名)

 

を実行したら、下記のような膨大なエラーが発生。。

  

エラーの一部抜粋

 

本記事はライトな日記思考で書いているので、詳細説明はしておらず、基本、テキストのみで画像とかはあまり載せておりません。。m(_ _)m

解説記事ではないため、解決していない内容や、その時々の間違った解釈を述べてしまっている可能性が大いにありますので、何卒、ご了承ください。

 

以前、整理したCloud Vision APIの使用方法(下記記事ご参照)に沿って、久しぶりに実行したのだが、うまく行かない。

 

 

結局、色々なことを試し、解決するのにかなり苦労した。。

 

本日記では、解決につながった方法のみ、履歴として残しておく。

 

先に結論をまとめておくと、必要だった対応は以下の通り。

 

  1. node.jsを更新する(16.10.0 または 18.0.0以上にする)
  2. Firebase CLIを最新に更新する(9.17.0 以降にする)
  3. npm install typescript@latest をする(最新に更新する)
  4. index.ts の try catch 文を修正する(引数の型判定を行う)

 

使用したFunctionsのサンプルコード

Google公式の下記GitHubに公開されている、画像認識用のコードを「git clone」して使用。

 

 

ちょうど4日ほど前(2022/11/10頃)に更新されたばかりの模様。

 

①node.jsのバージョンを「16.10.0」に更新

エラーの内容を見ると、TypeScriptで書かれているファイル(.tsファイル)に「,」や「]」が無い、といった文法系のエラーが出ている模様。

 

TypeScriptについては理解が乏しいが、バージョン差異による問題と思われたので、パッケージのイントールに用いるnode.jsのバージョンを更新(同時にnpmのバージョンも更新される)することにした。

 

本日記時点で、node.jsの最新バージョン(推奨版)は、「18.12.1」。

 

しかし、サンプルコードの「functions/package.json」ファイル内で、

 

"node": "16"

 

が指定されていること、

 

また、functionsフォルダ内で、「npm install」をした際に、

 

npm WARN EBADENGINE required: { node: '^14.15.0 || ^16.10.0 || >=18.0.0' }

 

の警告が出たこと、

 

を受け、「sudo n 16.10.0」のコマンドで、「16.10.0」に更新した。

 

※バージョンを指定してのインストールは、公式サイトからのインストーラーではできないようなので、まず「npm install -g n」でnode.jsのパッケージ管理ツール「n」をインストールし、「n」コマンドを使用できるようにした。

 

こちらの記事に大変助けていただいた(ありがとうございます!)。

 

 

②Firebase CLIを最新に更新

Cloud Functionsの下記公式説明

 

 

によると、node.js 16を使うには、Firebase CLIのバージョン「9.17.0」 以降を使用する必要があると書かれていた。

 

自分の使っていたバージョンを調べると、「9.16.0」でギリギリ未達。。。

 

※この要件を見落としていたので、バージョン関係の別のエラーも発生していて、解決に時間がかかってしまった。。

 

更新の方法は、下記公式サイト

 

 

に説明があるが、どうやっても「npm install -g firebase-tools」を使って更新するとエラーになるので、自動インストールスクリプト(下記コマンド)で更新した(現時点では「11.16.0」が最新)。

 

curl -sL https://firebase.tools | upgrade=true bash

 

※こちらのイシューによると、Firebase関連は「npm」だとうまく行かない事が多い模様。。

 

 

③TypeScriptのバージョンを最新に更新

node.jsとFirebase CLIを更新しただけでは、エラーは解消しないので、エラーメッセージでググると、類似した内容の下記記事が見つかった。

 

 

回答によると、「typescript」のバージョンを最新に更新すると良いとのこと。

 

サンプルコードの「functions/package.json」を見ると、「"typescript": "^3.8.0"」になっている。

 

そこで、記事内の情報どおり

 

npm install typescript@latest

 

を実行すると、「functions/package.json」の記載が、「"typescript": "^4.8.4"」に更新された。

 

この状態でデプロイしたところ、エラーメッセージが大幅に減り、以下のエラーのみになった。

 

############## % firebase deploy --only functions:annotateImage

=== Deploying to 'YYYYYYYYYY'...

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

> functions@ build XXXXXXXXXXXXXXX /functions-samples/vision-annotate-images/functions
> tsc

src/index.ts:25:54 - error TS2571: Object is of type 'unknown'.

25     throw new functions.https.HttpsError("internal", e.message, e.details);

src/index.ts:25:65 - error TS2571: Object is of type 'unknown'.

25     throw new functions.https.HttpsError("internal", e.message, e.details);


Found 2 errors in the same file, starting at: src/index.ts:25

 

ターミナルの画面上では、「e.message」と「e.details」の各「e.」の下に、エラーを示す赤い波線が出ていた。

 

④try catchの引数を「instanceof」で型判定するように修正

どうやら画像認識の関数を呼び出すサンプルコード「functions/src/index.ts」内の「try catch」文(エラーハンドリング)の文法に問題があるらしい。

 

調べると、関連しそうな下記記事が見つかった。

 

 

また、こちらのTypeScript公式のページ

 

 

を見ると、TypeScriptのバージョン4.0.0以降は、例外処理で渡される引数(上記では「e」)の型に応じて、処理を分ける必要があるらしい。

 

結果、以下のように「index.ts」を修正することとした。

 

↓index.tsの一部抜粋

export const annotateImage = functions.https.onCall(async (data, context) => {
  if (!context.auth) {
    throw new functions.https.HttpsError(
      "unauthenticated",
      "annotateImage must be called while authenticated."
    );
  }
  try {
    return await client.annotateImage(JSON.parse(data));
  } catch (e) {

    // ↓元のコード
    //  throw new functions.https.HttpsError("internal", e.message, e.details);

    //  ↓以下の内容に差し替え
    // 修正箇所 ここから
    if (e instanceof Error) {
      // Error型であることを確認したらエラーメッセージを投げる。e.detailsはエラーになるので削除
      throw new functions.https.HttpsError("internal", e.message);
    } else {
      // Error型でなかった場合も何らかthrowを書かないとエラーになる
      throw console.log("other issues");
    }
    // 修正箇所 ここまで

  }
});

 

else以下の部分を省略すると、下記のようなエラーになるので、仕方なくelseの場合は、console.logを表示するthrowを追加した。

 

 

以上で再度デプロイしたら、やっとのことで成功した!

 

 

(補足1)コンパイルオプションを修正

後で気づいたが、こちらの記事に説明があるとおり、TypeScriptのコンパイルオプション(compilerOptions)を「"strict": false」に設定すれば、try catch部分のエラーは発生しないとのこと。

 

確かに、サンプルコードの「functions/tsconfig.json」にあるTypeScriptのコンパイルオプション(compilerOptions)は「"strict": true」になっていた。

 

実際、これを「"strict": false」に修正してデプロイしたところ、エラーを回避できた。 

 

そのため、「index.ts」を修正したくない場合は、この方法も有効だと思われる(チェックが緩いコンパイルになる、ということだと思うので、若干不安ではあるが、、)。

 

 

(補足2)firebase-functionsとfirebase-adminを更新(未検証)

見落としていたが、、Cloud Functionsの下記公式ページ

 

 

を見ると、以下のような記述があった。

 

多くの場合、新しい機能とバグ修正は、最新バージョンの Firebase CLI とfirebase-functions SDK でのみ利用できます。 Firebase プロジェクトのfunctionsフォルダー内で次のコマンドを使用して、Firebase CLI と SDK の両方を頻繁に更新することをお勧めします。

npm install firebase-functions@latest firebase-admin@latest --save
npm install -g firebase-tools

(出典)https://firebase.google.com/docs/functions/get-started

 

別の影響が出ると困るので、試せていないが、「firebase-functions」の更新については、デプロイ完了時の警告メッセージにも出ていたので、もしかすると1行目のコマンドを実行しておけば、エラーは回避できたのかもしれない。。(なお、2行目のコマンドは、前述のとおり、curlコマンドで実施済)

 

(2022.12.17追記)

その後、

 

npm install firebase-functions@latest firebase-admin@latest --save

 

を試してみたが、結局これだけではエラーは解消しなかった

 

そのため、やはり前述の①〜④の対処が必要、というのが現時点での結論。。

 

 

Firebase CLIやnpm絡みでは、毎回バージョン関係のエラーで苦労する。。

 

\一般的なエラー対処法をまとめた記事はこちら/

 

リリースしたアプリ(全てFlutterで開発)

 

個人アプリ開発で役立ったもの

おすすめの学習教材

超初心者向けでオススメな元Udemyの講座/

 

 \キャンペーン時を狙えば安価で網羅的な内容が学べる(日本語訳あり)/

 

\Gitの基礎について無料で学べる/

 

おすすめの学習書籍

実用的image_pickerに関してかなり助けられた/

 

Dartの基礎文法を素早くインプットできる/


Dart入門 - Dartの要点をつかむためのクイックツアー

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