背景
※執筆時点のfirebase-toolsは8.12.0です。
TermuxでFirebaseのエミュレータを起動したかった。
Termuxでもfirebase-toolsが入れられるので、firebase emulatorsも当然使えると思ったがそうはいかなかった。
firestoreとdatabaseのエミュレータはJavaで実装されているが、TermuxにはJavaが用意されていないため起動できない。
そこで、Javaのインストールからfirebase emulators:start --only firestore
を起動できるまでの手順を紹介する。
手順
0. 準備
既に一通り済んでいる場合は飛ばす。
Termux
PlayストアからTermuxをインストールする。
Termuxパッケージ
最低限以下のパッケージが必要になるので、Termux上でインストールする。
- proot
- wget
- vimなどのテキストエディタ
- nodejsまたはnodejs-lts
- firebase-tools
1. Javaのインストール
前述の通り、Javaが用意されておらずパッケージもない。
しかし、Termux-Javaと言うスクリプトを使えば一応Javaが使えるようになる(一応とした理由は後述する)。
$ wget https://raw.githubusercontent.com/MasterDevX/java/master/installjava && bash installjava
これでJavaが使えるようになる…はずだが、筆者の環境ではBad system call
と言うログとともにJavaがkillされた。
Issueによればroot権限が必要なようなので、proot
を併用して起動するか確認する1。
$ proot java
2. firebase-tools(firestoreエミュレータ)の修正
firestore及びdatabaseのエミュレータはjarファイルで提供されており、javaコマンドで実行するようになっている。
この時、javaコマンドはchildProcess.spawn()
を使って実行しているが、PATH
からjavaコマンドを探して実行するため、仮にaliasでproot java
に設定していたとしても関係なく素のjavaコマンドを実行し、Bad system call
で起動に失敗する。
なので、ここは少し強引だがfirebase-toolsのソースコードを直接編集して対応する。
編集対象となるファイルはdownloadableEmulators.tsなので、ローカル環境でこのファイルを捜索してテキストエディタで開く。
firebase-toolsをグローバルにインストールしている場合は、デフォルトでは
/data/data/com.termux/files/usr/lib/node_modules/firebase-tools/lib/emulator/downloadableEmulators.js
として存在している(はず)。
118行目、124行目あたりを以下の通りに修正する。
Line: 118
database: {
- binary: "java",
- args: ["-Duser.laungage=en", "-jar", getExecPath(types_1.Emulators.DATABASE)],
+ binary: "proot",
+ args: ["java", "-Duser.laungage=en", "-jar", getExecPath(types_1.Emulators.DATABASE)],
Line: 124
firestore: {
- binary: "java",
- args: ["-Duser.laungage=en", "-jar", getExecPath(types_1.Emulators.FIRESTORE)],
+ binary: "proot",
+ args: ["java", "-Duser.laungage=en", "-jar", getExecPath(types_1.Emulators.FIRESTORE)],
要するに、javaではなくprootを実行し、引数としてjavaを渡すように変更する。
3. 確認
これでエミュレータが動作するはずなので、プロジェクトディレクトリに戻ってエミュレータを起動する。
$ firebase emulators:start --only firestore
問題点
エミュレータ終了時にjavaのプロセスが残る
エミュレータの終了に失敗し、firebaseプロセスの子プロセスであるはずのjavaが残り続けてしまう。
このjavaプロセスは8080ポートを占有しており、続けてエミュレータを起動しようとすると8080ポートが空いていないことによってエミュレータが起動できなくなってしまう。
現時点では原因がわかっていないため、都度プロセスをkillして対応する2。
$ lsof -i:8080
# -> 8080を占有するjavaプロセスのpidがわかるはずである。プロセスがない場合は問題が発生していないので、そのままエミュレータを起動できる。
$ kill javaプロセスのpid
firebase-toolsのコードを編集している
編集せずにうまいことやる方法があったら教えてください。
ブラウザの開発ツールがない
この記事の主題とは直接関係ないが、hostingエミュレータを使えば作ったソースコードをlocalhostで閲覧できる。
しかし、閲覧に使用するブラウザはAndroidアプリなので開発ツールがなく、デバッグできない。
参考
解決に時間がかかったので、残っていたタブから抜粋。実際にはもっとたくさんのページを閲覧した。
- https://termux.com/
- https://firebase.google.com/
- https://github.com/firebase/firebase-tools
- https://github.com/MasterDevX/Termux-Java/issues/7
-
https://qiita.com/shintarogit-on-qiita/items/70f193829f4360dca771
- javaコマンドをどのようにして起動しているかを調べた。
-
https://swfz.hatenablog.com/entry/2019/10/07/001242
- patch-packageでうまいことしたかったが、グローバルインストールだったので断念した。ローカルならいけるかもしれない。
-
https://qiita.com/tacchi/items/a532aafd9c05fdf7be45
- Termuxのセットアップの参考にした。
- Ubuntu(LXDE, TermuxとUserLAndの両環境)も試したが動作が重く、Firefoxに何も表示されなかったので断念した。デスクトップが快適に動く環境ならLinux版のブラウザが使えるので開発ツールも使えるはず。
-
https://knowledge.sakura.ad.jp/21687/
- 筆者はそもそもvimmerではない。しかし、恐れていたほどではなかった(傲慢)。