わしのlog

プログラミングとかバイクとか。

【メモ】Cloud Functions for Firebase用の関数をWSLでデバッグする際、認証情報を使う

概要

Google Cloud Functions for Firebaseでは
ローカルデバッグ用のエミュレータが利用できるようになっています。

firebase.google.com

このローカルデバッグ時に認証情報が必要な処理があった場合
認証エラーとなってしまう件についてのメモ。
いつも通り、WSLでのお話。

環境

OS: Windows 10 Pro 64bit(with WSL)

詳細

firebase.google.com

こちらのチュートリアル通りにすすめていくと、4. 必要なモジュールをインポートしてアプリを初期化するの項で
firebase-admin を使用する旨が書かれています。
この処理をデバッグ時に通すと認証エラーになってしまいます。
(tokenとか指定してないので当たり前なんですが・・・)
で、公式ドキュメントを漁ってみると・・・ありました。

firebase.google.com

手順通りにすすめてみる

ほうほう、まず秘密鍵ファイルを作成して、任意の場所に保存。
その後コンソールでexport GOOGLE_APPLICATION_CREDENTIALS="/path/to/hoge.json"を実行しなさい、と。
(ただし一時的なもの=現在のコンソールでのセッションでのみ有効)
別途コード内にベタ書きする手法も書いてますが、推奨されてないみたいですね。

ではでは同様の手順を実行して、と・・・。

[yyyy-mm-ddThh:mm:ss.SssZ]  @firebase/database: FIREBASE WARNING: {"code":"app/invalid-credential","message":"Credential implementation provided to initializeApp() via the \"credential\" property failed to fetch a valid Google OAuth2 access token with the following error: \"Error fetching access token: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal metadata.google.internal:80. Error code: ENOTFOUND\"."}

うん、ダメやないかい
多分環境変数が読めてないんだろうな~
ってことで該当のnodeモジュール内にconsole.logを仕込んでみることに。
えーと・・・firebase_admin/lib/auth/credential.js・・・これかな。
getApplicationDefault関数内で該当の環境変数を読み取ってそうなところがあったので、そこに仕込むと・・・
undefined
やっぱり。

他の手法を探す

  • ホスト側(Windows)の環境変数GOOGLE_APPLICATION_CREDENTIALSを設定してみる
    →駄目。cmdやらPowerShellで実行するなら問題なさげですが・・・
  • node_modulesを削除して再度npm iして実行
    →駄目。今回の件には全く関係ない
  • 前回の記事通り、コマンド実行時に環境変数を定義して渡す。
    →いけました。WSLだとこれじゃないと駄目?
    ※参考記事

dev-daikichi.hatenablog.com

この記事にあるように、以下コマンドを実行
GOOGLE_APPLICATION_CREDENTIALS="/path/to/hoge.json" npm run serve
(package.jsonにscriptsがあったのでこのコマンド。恐らくfirebase emulators:startでもOK)
やっと実行できましたね。

終わりに

今回はWSLでGCF for Firebaseのデバッグ実行について書きました。
強制的に環境変数を定義する手法でなんとかなりましたが、他にいい方法があれば
誰か教えていただけると助かります・・・。
とりあえず、これでWSLでのデバッグ実行は問題ないですね。

現場からは以上です。

Cloud Functions for Firebaseを試してみた

概要

Cloud Fucntions for Firebaseを試してみました。
環境はWindows 10 Pro 64bitWSL上にて実行。

実行メモ

一応チュートリアル通りに進めていきます。 firebase.google.com

まずはFirebaseコンソール上でプロジェクトを予め作成しておきます。
この辺りは先人の方たちに語り尽くされているので割愛。

まずはfunctionsの初期化コマンドを打ちます。
firebase init functions
f:id:devdaikichi:20200330164740p:plain
f:id:devdaikichi:20200330165219p:plain
このディレクトリをプロジェクト(firebaseの)に紐づけるためのオプションを指定してください
とのことなので、とりあえずUse an existing Project.を選択。
Firebaseに作ってあるプロジェクトを指定します。

次はJavaScriptとTypeScriptどっちを使うかと聞かれました。

f:id:devdaikichi:20200330170741p:plain
今回はこちらにも書いたように、TypeScriptのオライリー本を購入したので
TypeScriptを選択してみます。

次はTSLint(JSを選択していたらJSLint)を使うか?と聞かれるので、Y

次はnpmの依存パッケージを今すぐダウンロードします?と聞かれるので、Y

しばらくするとfunctionsディレクトリに色々とファイルが作成されます。

後はチュートリアル6. addMessage() をデプロイして実行するの通りに関数を追加
firebase deploy --only functionsを使ってデプロイ。
余談ですが、ここでデプロイする関数を絞ることもできるようです。
が、余りデプロイ速度は変わらないみたいです。。。
また、プロジェクトのルートディレクトリで上記コマンドを実行したのに、どうやって
デプロイ対象のディレクトリを指定してるんだろう・・・
と思ってたんですが、ここに書いてましたね。

firebase.google.com

デフォルトでは、Firebase CLI によって functions/ フォルダ内でソースコードが検索されます。
別のフォルダを指定するには、firebase.json に次の行を...
大体予想してましたが、デフォルトではfunctions/配下が選択されるんですね。
で、別ディレクトリを参照させるならfirebase.jsonに指定すると。
すっきりしました。

デプロイが完了したら、Function URL (addMessage): https://us-central1-Y_PROJECT.cloudfunctions.net/addMessage
のように出力されるので、ブラウザにクエリパラメータを付加した上記URLを入力してアクセス。
すると、データベースにクエリパラメータで指定した文字列が登録・・・
f:id:devdaikichi:20200330174737p:plain
されませんでした。
というのも、この時私はChromeで2つのGoogleアカウントでログインしており
開発用アカウントではなくメインアカウントの方で叩いてしまったので
URLを叩いたあとのFirebaseコンソールページへのリダイレクトで、アクセス制限に引っかかっているようでした。
つまり、登録はできているけど登録を確認する為のリダイレクト処理でうまくいってなかっただけ、みたいです。

新たにシークレットタブを開き、開発用アカウントでログインし、実行すると・・・
f:id:devdaikichi:20200330175108p:plain
登録されましたね。

終わりに

今回はチュートリアルに従って、Cloud Fucntionsを使ってみました。
Firebaseはドキュメントも充実しているし、簡単な操作でデプロイできるのでいいですね。
次は画像アップロード用の関数でも作ろうかなぁと思っています。

現場からは以上です。

【メモ】WSLでfirebase login しようとするとエラーで落ちる

概要

WSL上でfirebase login しようとするとError: An unexpected error has occurred.と表示され、ログインできない。

ログ

実行ディレクトリに生成されるfirebase-debug.logのエラー内容を見てみると

[debug] [yyyy-mm-ddThh:mm:ss.SssZ] Error: spawn cmd.exe ENOENT
    at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
    at onErrorNT (internal/child_process.js:415:16)
    at process._tickCallback (internal/process/next_tick.js:63:19)
[error] 
[error] Error: An unexpected error has occurred.

Windowsのcmdを参照しようとして、うまく参照できなくて落ちてる?

解決方法

それっぽいissueがありました。
github.com
なるほど。
PATH="$PATH:/mnt/c/Windows/System32" firebase login
上記コマンドを実行せい。と書いてありますね
コマンド実行時に環境変数を強制的に定義して実行すればいいんですね。
試してみると...
f:id:devdaikichi:20200330164105p:plain
うまくログインできましたね。

終わりに

WSLが登場して、だいぶ便利になりましたが
いまだにすんなりいかない時がありますねぇ。
試していないのでわかりませんが、WindowsPATHを引き継がないようにする
下記記事のような方法も手かもしれません。

qiita.com


現場からは以上です。

2019年は暴食の年だった

はじめに

この記事は大都会岡山 Advent Calendar 201920日目の記事です。

どうも皆さんこんにちは。
絶賛ブログサボり中のだいきちです。
何を書こうかな〜と思っていたら、いつの間にか当日が来ていたというよくあるアレです。
技術系の記事を書きたかったんですが、またの機会に勉強会のことも絡めて書こうかなと思います。

本題

さて、タイトルの「暴食」について。
岡山に戻ってきてはや2年、実は体重が10kgほど増えました。
控えめにいってヤバイ、やっぱり故郷の料理は美味いです。
ちなみに私の腹のキャパはココイチ1kgとか、二郎系大盛り野菜マシマシくらいまではいけるアレです。
増え始めたのはアレかな、

f:id:devdaikichi:20191219220533j:plain
加藤商店さんのラーメン並野菜マシマシ
コレとか
f:id:devdaikichi:20191219220910j:plain
ラーメンどかいち さんの野菜マシ
コレとか食べてたからだろうなぁ・・・
(故郷の味関係無い説)
本業も座り仕事ですし、とりあえず暴食を止めようと思います。
この前風呂場で自分のお腹を見て3秒間くらい地獄のオーラを纏ったので。

おわりに

岡山の二郎系ラーメンの紹介でした(?)
特に加藤商店さんはハマっていて、お弁当が無い時はよく行っています。
ただし月曜は空いていないのと、晩くらいには麺が無くなって閉まっている・・・なんてことがよくあるので
来店される方は気をつけてください。
本当は岡山のツーリングスポットやら、私がよく行く店やら紹介したかったのですが
いかんせん写真が無い!w
後日抱負記事を書くのですが、実生活も「写真なり動画なりでログに残すこと」みたいな抱負を入れておこうかな・・・。

現場からは以上です。

gitlab-runnerを使って.NET Frameworkのプロジェクトをビルドする

はじめに

こんにちは、だいきちです。
今回はgitlab-runnerを使って.NET Framework製のプロジェクトをビルドしてみたいと思います。
MSBuildを使用するため、runnerの登録はWindows側にしています。
悪戦苦闘したので、備忘録として。

環境

runnner側: Windows10 pro
GitLab側: Ubuntu 18.04 LTS

手順

今回はこの記事を参考にさせていただきました。
qiita.com

1. 証明書の作成

openssl.cnfを編集し、subjectAltnameUbuntuIPアドレスを追記
※注: 記事中はopenssl.cnfの階層が/etc/pki/tls/となっていますが
今回はUbuntuなので/usr/lib/ssl/となります。
次に、記事コマンドを参考に、ubuntu上にserver.keyserver.crtを生成。

2. gitlab.rbの編集

秘密鍵と証明書のパスを追記しておきましょう。

nginx['ssl_certificate'] = "秘密鍵のパス"
nginx['ssl_certificate_key'] = "証明書のパス"

その後は、下記コマンドでGitLabをrestart

$ sudo gitlab-ctl reconfigure
$ sudo gitlab-ctl restart

3. Tokenの確認

CIを行う対象GitLabプロジェクトのページに移動し
Settings > CI/CD > Runners を開いて、Set up a specific Runner manuallyに書いてある
URLとTokenをコピーしておきます。

4. GitLab-Runnerのインストール

公式の手順を参考にインストールしましょう。
○ダウンロードURLからexeファイルをダウンロード
○リネームして任意の場所に配置
とりあえずここまでが終わったら、一旦Windows側にサーバ証明書をインストールしてやります。
参考記事証明書のインストール参照。
これまたこの記事を参考にさせていただきました。

qiita.com

  1. WinSCP等でUbuntu側からserver.crtファイルを持ってくる
  2. PowerShellを管理者権限で開いて、server.crtがあるディレクトリに移動。
    その後、certutil -addstore -f -user "ROOT" server.crt を実行。
  3. gitlab-runner.exeがあるディレクトリに移動
    その後、gitlab-runner.exe registerコマンドを使用
    対話形式で情報を聞かれるので順に
    ○先程確認したURL
    ○先程確認したToken
    ○GitLabRunnerの説明
    ○タグ(任意)
    ○タグがつけられていないジョブを実行するかどうか
    ○GitLab Runnerを現在GitLabにあるプロジェクトのみで使用するかどうか
    ○GitLab Runnerのタイプ→私はpowershellを選択
  4. runnerのユーザ登録を行う
    gitlab-runner.exe install --password [ログイン中のWindowsユーザのパスワード]

5. GitLab-Runnerの起動

いよいよ起動です。
ここでgitlab-runner.exe startと実行すると・・・
私の場合、起動しませんでした
他の方の記事を見ているとこのコマンドで起動できているみたいなのですが
どうやら私はgitlab-runner.exe runでないとうまく起動しないようです。
だれか知見のある方いらっしゃいましたら教えていただきたい・・・。

gitlab-ci.ymlの作成

一応、私はこんな感じで作りました。
IISを使ったことのある方は見覚えのあるディレクトリがあるかと思います。

variables:
  UNITTEST_FOLDER: './tests/bin/Release/'

stages:
  - build

# build用のjob
build_job:
  stage: build
  only:
    - branches
  script:
    - chcp 65001
    - 'nuget restore ./hogeProject'
    - 'msbuild ./hogeProject/hoge.sln /nr:false /p:Configuration=Release /clp:ErrorsOnly'
  artifacts:
    expire_in: 2 days
    paths:
      - '"%UNITTEST_FOLDER%"'

ちょっと勉強不足感もあり、artifacts配下のpathsはほぼ意味を為していません(ぇ
書いてあることはほぼほぼそのままなんですが、deploy時のscriptはごっちゃごちゃなのであえて載せていません。

後は該当プロジェクトにpush時、CIが動いているか確認してあげましょう。

その他

gitlab-ci.ymlでの注意点

○gitlab-ci.ymlでWindows環境での環境変数の指定の仕方が違う
powerShellを使っているので当たり前なのですが、環境変数に用いる記号が違います。
linux: $hoge
windos-cmd: %hoge%
windows-powershell: "env:hoge"
といった感じ。

MSBuild時のエラー対応

GetReferenceNearestTargetFrameworkTaskエラーが出る場合

こちら参照

developercommunity.visualstudio.com

要するにMSのBuildToolsを開いて
「Nuget targets and build tasks(ナゲットターゲットとビルドタスク)」にチェック入れて変更を押すだけ。

error MSB4226: "C:\Program Files (x86)...Microsoft.WebApplication.targets" が見つかりませんでした。

また先程のインストーラを開いて「Web開発ビルドツール」をチェックして変更。

まとめ

備忘録なので走り書きのような形になってしまいましたが、このような感じです。
抜け等ありましたらまた加筆・修正します。

現場からは以上です。

react-routerを使ったアプリケーションでURL直叩き(or F5)すると404になる

はじめに

こんにちは、だいきちです。
今回はreact-routerを使用し、serveを使ってローカルにサーバを立てた時
/以外のURLで404となってしまう現象について書きます。
恐らくタイトルだけ見て「ははぁ~ん?」となった方もいるでしょう
ですが、私は初学者ゆえわからず・・・
結果としては公式ドキュメントちゃんと読めよという話でした。(自戒

環境

  • create-react-app(CRA) : 2.1.3
  • react-router: 4.3.1
  • serve: 11.0

なぜ404?

この辺りを参照。
qiita.com

teratail.com

要するに、サーバ側にrewriteの設定が必要な訳ですね。
2つ目のQ&Aを見るとわかると思いますが、サーバ側が返しているのはあくまでindex.html
react-routerがURLに対応するコンポーネントを切り替えているだけなので、
URLにマッチするリソースは存在しません = 404となるわけですね。
なるほど、わかりやすい。
Reactって動的にindex.htmlを書き換えてるだけですもんね、仮想DOMを使って。
(間違ってたらスミマセン)

解決策

で、本題の解決策なんですが、ぶっちゃけるとserveでは解決してません。
serveのREADME見るとそれっぽいこと は書いてあるのですが
まず
create-react-appの公式ドキュメントにそれっぽいことは書いてないか?
という疑問が浮かんだので、調べると...
ありました
なになに...

If you use routers that use the HTML5 pushState history API under the hood (for example, React Router with browserHistory), many static file servers will fail.  
google様訳: HTML5 pushState history APIを内部で使用するルーター(たとえば、browserHistoryを持つReact Router)を使用すると、多くの静的ファイルサーバーが失敗します。


ですよねー

と、いうわけで下の方に行くと、Expressを使用した例が。
素直にExpressをインストールして使用しました。
npm install express --save
その後、プロジェクトルートにserver.jsを作成。
後は公式ドキュメントのソースをコピペ。

const express = require('express');
const path = require('path');
const app = express();

app.use(express.static(path.join(__dirname, 'build')));

app.get('/*', function(req, res) {
  res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

app.listen(9000);

npm run build でアプリケーションをビルド。
node server.js でサーバ起動。http://localhost:9000に接続すれば
アプリケーションの起動が確認できると思います。
後はURLを直叩きしても404にならない優しい世界をご堪能下さい。

余談

先ほどserveでは実装しませんでしたが、やはりconfigっぽいのを定義すればいけるんじゃないでしょうか。
(下記参照。※検証はしていません。)
spectrum.chat

まとめ

最初にも書きましたが、公式ドキュメントは読みましょう。
もう一度言います、公式ドキュメントは読みましょう

現場からは以上です。

私が東京から岡山に移住(リターン)した理由

はじめに

だいきちです。
ふと思い立って書いてみようと思いました。
私が新社会人として東京に就職したのが約3年前。
そこから1年半ほど東京で働きました。
諸事情もあり、地元である岡山に転職を決め、リターンしてきました。
(詳細は後述)
そこで、2つの環境の違い等をまとめてみようと思ったわけです。
都会から地方への移住を検討している方の参考にでもなればいいかなと思います。

退職理由

続きを読む