つばくろぐ @takamii228

知は力なり

「私の情報の集め方、知識の学び方」を書き直した

以前自分の情報収集のやり方について以下のブログにまとめていました。

takamii.hatenablog.com

ここではGitPitchというサービスを使ってgithubリポジトリにおいたmarkdownからスライドを生成していたのですが、このGitPitchが2021/3/1にサービスが終了するそうです。

Service on gitpitch.com is shutting down on March 1, 2021.

github.com

そこで内容を一部修正、加筆しつつスライド化してspeakerdeckに再アップロードしました。

speakerdeck.com

コロナでリモートワークがメインになって変わってたところもあるなーと修正していて感じました。

まとめていた内容はライフステージの変化や自身の置かれた状況によって変わりそうなので、定期的に見直すと良さそうだなと思いました。

Firebase App Distributionを使って内部向けに継続的にネイティブアプリを配信する

はじめに

ネイティブアプリの内部テストを円滑にすすめるために、Firebase App Distributionを使ってアプリを配信する仕組みを触る機会があったので手順をまとめておきます。

Visual Studio App Centerを使ったアプリ配信の仕組みについては以前まとめたこちらをご確認ください。

takamii.hatenablog.com

Firebase App Distributionとは

Firebase App DistributionはFirebaseに含まれるアプリ配信機能です。モバイルアプリ開発において、Push通知機能やCrashlytics・Analyticsの連携などでFirebaseを使う機会は多いと思います。開発したアプリを実機に配信する方法はケーブルをつないで手動でインストールする方法もありますが、このようなアプリ配信サービスを使うことで、開発中のアプリをインターネット越しにアプリを配信することができます。リモートワークが当たり前になった今、モバイルアプリの内部配信にうってつけの機能ですね。

firebase.google.com

Firebase App Distributionには以下の特徴があると公式に記載されています。

  • Cross-platform
  • Fast distributions
  • Fits into your workflow
  • Tester management
  • Works with Crashlytics

配布対象はAndroidiOSアプリに対応していて、CLIやFastlane経由で利用できるようです。またアプリの配信先としてテスターグループが管理できるようです。 ただしFirebase App DistributionはまだBetaマークがついているので正式版ではない点に注意が必要です。

今回はベータ版ではありますが、Firebase App Distributionを使って実際にアプリを配信して実機端末にインストールするまでの手順をまとめます。

1. Firebaseプロジェクトを作成する

まずFirebaseコンソール上で今回の検証用の新しいFirebaseプロジェクトを作成します。Push通知やCrashlytics用にすでにプロジェクトがある場合は不要です。

プロジェクトを作成したら配信用のiOSAndroidのアプリをFirebaseプロジェクトと紐付けます。Push通知やCrashlyticsのときと同様にアプリのApplication ID、Bundle IDを入力するとFirebaseの連携用のjsonファイル・plistファイルがダウンロードできます。

f:id:takamii228:20210110161957p:plain

f:id:takamii228:20210110153646p:plain

このあとそれぞれアプリにFirebase SDKを組み込んでビルドをするのですが、Firebase App Distributionの利用のみであればApplication ID、Bundle IDの登録までで大丈夫です。以下のスクリーンショットのようにアプリが登録されていれば設定は完了です。

f:id:takamii228:20210110162145j:plain

ここに表示されているApp IDは後で利用するのでそれぞれメモしておきましょう。

2. apkファイル・ipaファイルを作成する

Visual Studio App Centerのときと同様に、ここではビルド済みのapkファイル・ipaファイルを配布するというシナリオにします。

今回もFlutterのプロジェクト作成時のアプリをベースにapkファイルとipaファイルを作成しておきます。こういうときはクロスプラットフォームは便利ですね。

apkの署名はデフォルトのデバッグプロファイルで、ipaは後でインストールする端末の情報を含んだprovisioning profileファイルで署名したものを用意します。

なおFlutterを使ってapk・ipaファイルを作成する手順はこちらを参考にしてください。

takamii.hatenablog.com

3. Firebase App Distributionへapk・ipaファイルをアップロードする

Firebase App Distributionへのアップロード方法は以下の方法があります。

  • Firebase Console上で手動でアップロードする
  • Firebase CLIを使う
  • fastlaneを使う
  • Gradle Pluginを使う(Androidのみ)

今回はCI/CDパイプラインでの利用を想定して、2番目のFirebase CLIを利用することにします。

Firebase CLIを公式のガイドに沿ってインストールします。

firebase.google.com

今回利用したバージョンは以下です。

$ firebase --version                   
9.1.2

Firebaseへのアップロードするために利用するトークンは以下のコマンドで発行することができます。

$ firebase login:ci

コマンドを実行するとGoogleの認証画面が立ち上がるので、さきほど作成したFirebaseプロジェクトに紐づくGoogleアカウントで認証します。認証が成功するとトークンが取得できます。

$ firebase login:ci

Visit this URL on this device to log in:
https://accounts.google.com/o/oauth2/auth?xxxxxxxx

Waiting for authentication...

✔  Success! Use this token to login on a CI server:

1//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Example: firebase deploy --token "$FIREBASE_TOKEN"

Firbease CLIを使ったApp Distributionへのアップロードコマンドオプションは公式ドキュメントに記載されています。パラメータ一覧は以下になります。

  • app : Firebaseで登録したApp ID
  • token : Firebaseのアクセストーク
  • release-notes (release-notes-file) : リリースノートの文字列(ファイル)
  • testers / (testers-file) : アプリのインストールを招待するメールアドレス、複数の場合はカンマ区切り(ファイル)
  • groups / (groups-file) : アプリのインストールを招待するグループ、複数の場合はカンマ区切り(ファイル)
  • debug : デバッグフラグ、オンの場合はログファイルを出力する

appは先程メモしたApp ID、tokenは発行したアクセストークンを指定すればよさそうです。

配信対象のテスターやグループはまだ未設定だったのでFirebase Console上で作成します。今回はサンプルとしてDevelopersグループとSalesMembersというグループを異なるメールアドレスで1つずつ設定してみました。

f:id:takamii228:20210110160248j:plain

設定するパラメータが準備できたので、あとはCLIを実行するだけです。App Centerと違ってFirebaseの場合はワンライナーでかけます。上記のApp Distribution用のパラメータに加えて、FirebaseのプロジェクトIDも忘れずに設定しましょう。

$ firebase appdistribution:distribute ${UPLOAD_FILE_PATH} \
 --token "${FIREBASE_AUTH_TOKEN}" \
 --project "${FIREBASE_PROJECT_ID}" \
 --app "${FIREBASE_APP_ID}" \
 --release-notes "${RELEASE_NOTE}" \
 --groups "${GROUP_NAME}" --debug

アップロードに成功すると以下のようなログが表示されます。

...
✔  uploaded distribution successfully! 
i  adding release notes... 
...
✔  added release notes successfully 
i  adding testers/groups... 
...
✔  added testers/groups successfully 

コンソール画面を見るとアプリがアップロードされていることがわかります。

f:id:takamii228:20210110162751j:plain

Androidアプリと同様にiOSアプリもアップロードします。

f:id:takamii228:20210110163112j:plain

4. アプリを端末にインストールする。

アップロードが完了するとDevelopersに登録したメールアドレスにメールが届いているので、インストールする端末でメールを確認します。

Android上でapkファイルをインストールする

メールの案内に従ってアプリをインストールします。メールを開くとFirebase App Distributionへの権限追加の案内がでるので内容を確認して許可してインストール画面へ遷移します。

インストール画面ではFirebase App Tester Appのインストールのポップアップが出ます。これはWeb APKというやつなのだろうか、案内に従ってインストールします。Google Play以外からのインストールなのでもろもろの権限の追加を行ってインストールします。

f:id:takamii228:20210110164622j:plainf:id:takamii228:20210110164727j:plainf:id:takamii228:20210110165024j:plainf:id:takamii228:20210110165120j:plain

Firebase App Tester上で利用するGoogleアカウントで認証し、もろもろの権限を設定すると配信中のアプリがダウンロードできるようになります。リストにあるアプリをダウンロードすると無事配信されたアプリをインストールすることができます。

f:id:takamii228:20210110165438j:plainf:id:takamii228:20210110165605j:plain[f:id:takamii228:20210110165636j:plainf:id:takamii228:20210110165647j:plain

iOS上でipaファイルをインストールする

iOSも同様にメールの案内に従ってアプリをインストールします。一連の作業はSafariで行う必要があるためSafariの起動を促されます。SafariでコピーしたURLを起動してGoogleアカウントで認証します。

f:id:takamii228:20210110163916j:plainf:id:takamii228:20210110165935p:plainf:id:takamii228:20210110170010p:plainf:id:takamii228:20210110164024j:plain

iOSの場合はFirebase App DistributionからのOver The Air方式でのアプリのインストールを許可するために、プロファイルのインストール作業が別途必要になります。合わせてFirebase App Distributionへデバイス登録の処理が走ります。

f:id:takamii228:20210110164032j:plainf:id:takamii228:20210110170333p:plainf:id:takamii228:20210110170358p:plainf:id:takamii228:20210110170420p:plain

プロファイルの設定が完了するとアプリがインストールできるようになります。Firebase App Testerへのショートカットもホームスクリーンに追加されていますね。

f:id:takamii228:20210110164230j:plainf:id:takamii228:20210110164243j:plainf:id:takamii228:20210110170611p:plainf:id:takamii228:20210110170658p:plain

以上がFirebase App DistributionでのAndroidiOSアプリの配布・インストール手順になります。

インストールしたあとにコンソール画面を見てみるとちゃんとインストールされた数がカウントされています。

f:id:takamii228:20210110170935p:plain

f:id:takamii228:20210110170947p:plain

5. テストグループを使った権限制御

上記の手順ではDevelopersグループへの配信を行っていました。試しにSalesMembersのアカウントでダウンロード画面を見てみたら以下のような画面になっていました。きちんと配信対象の制御ができてそうです。

f:id:takamii228:20210110171303j:plainf:id:takamii228:20210110171312p:plain

パイプラインとの統合

以上の検証からFirebase CLIを使ってApp Distributionを使ったアプリ配布ができました。 あとはtag pushやreleaseブランチ作成契機でapkファイル作成、ipaファイル作成を行った後に、Firebase CLIを使ってApp Distributionにアップロードするパイプラインを作成すれば、以下のようなモバイルアプリの継続的デリバリーを実現するCDパイプラインが実現できそうです。

Release Noteパラメータにtag名を連携するとアプリのバージョン区別として利用できそうです。

f:id:takamii228:20210110172014p:plain

その他の機能

Firebase App Distributionはアプリの配布以外にもiOSのみですが、in-app alertsという機能が提供されているようです。 こちらをアプリに組み込んでおくと、最新のアプリが配布された場合にアプリ上でダイアログで教えてくれるようになるようです。

firebase.google.com

その他のアップデートは11月の公式ブログで紹介されています。SDK経由でこれから様々な機能追加が期待されますね。

firebase.googleblog.com

まとめ

以上がFirebase App Distribution経由でapk・ipaファイルを配信する手順になります。

内部で手軽にアプリを配信できるような仕組みを用意しておくことで、モバイルアプリでもサーバサイドと同等レベルのよりEnd-to-Endの継続的デリバリーが実現でき、QAやUI確認等の開発のフィードバックライフサイクルをより短縮することができるでしょう。

2020年の振り返り的な何か

今年もやる。去年のはこちら。

takamii.hatenablog.com

2020年にできたこと

iOSAndroidアプリ開発完全に理解した

仕事でiOS、Androoid、Flutter、React Native、React.js等々のクライアントアプリをメインで見るようになったので、いわゆるネイティブアプリ開発で必要なこととか考えるべきことがわかるようになった。

昨年はFlutterをメインに触っていたのだけど、それぞれのネイティブでSwiftUIとかArchitecture Componentとかもわかるようになった。新しい仕事でも導入できていてよい。

特にiOSの証明書周りはなるほどわからん状態だったけど、アプリリリースまでに必要な作業が何なのかは手を動かしながらわかるようになった。

WWDCの動画も追っかけたし、AndroidのCodeLabもそれなりに触ったので、ちゃんと活用できるようにしたい。

フロントエンドの設計を理解できた

iOS、Androoidに加えてReactもちょこっと見たので、出てくる単語とか根幹にある設計思想とかなんで生まれてきたのかの表層はなんとなく理解できるようになったし技術選定の議論の土壌には立てるようになった。

ただまだ0から一人でソースコードとセットで組めるかっていうと少し自身がないのでまだ精進が必要だと思う。

React、Flutter、SwiftUI、Jetpack Composeと宣言的UIの考え方がベースになってきたり、Atomic Designとかもあったり、MVP / MVVM / Flow / Clean Architectureなどなど群雄割拠なフロントエンド界隈を俯瞰して見れるようになるのはそれはそれで楽しいなと感じる。

今年は幸い仕事で強い方々と会話できたり教えてもらえる機会も多かった。今の組織ではこの歳や年次になると、より専門的な内容の中身に関してボコられる(※自分の想像の枠を超えたり、間違いを指摘してくれるフィードバックをもらうこと)機会が減っていると感じるのでとてもありがたい。技術領域的に社内で誰もやってないことが多いので、結局は自分でどうにかしたり外にフィードバックもらいに行くしかないなと思った。

フロントエンドにおける認証認可について考えた

仕事でモバイルアプリやSPAでOAuth2.0 + Open ID Connectを実装する時に何を考えなきゃいけないかとか、どういう設計にするべきなのかを結構考えた。

PHPのサーバーサイドでの実装は何回かやったことあったのだけど、モバイルアプリやSPAだと間にセッション層作ったりアクセストークン・リフレッシュトークンどうやって管理したらいいかとか、ブラウザクラスどうするのとか結構悩んだのはいい経験だった。

いろいろ整理してアウトプットしたいなと思いつつ時間が立ってしまっている...。

Flutterの登壇発表した

昨年のFlutterの成果の出口を探してたのだけどなかなか良さげなイベントがなかったのでブログにまずはまとめていた。そんな矢先、10月にちょうどDevFest TokyoのLT募集があったのでおうちから登壇した。

takamii.hatenablog.com

ISUCONに出た

ISUCONにも出れて、昨年よりもいいスコアが出せてよかった。途中まで順調だったのが悔しい。来年も開催されたらリベンジしたいな。

takamii.hatenablog.com

ブログを月1ペースで投稿できた

去年に引き続いて月1投稿ペースを維持できた。iOSの証明書の話はTwitterで参考になったってフィードバックがもらえてよかった。

f:id:takamii228:20201230163912p:plain

takamii.hatenablog.com

TOEICスコア(785)を更新する

2月に受けたけど、また785だった。ノー勉凸だったので妥当。。。

振り返り

良かったこと・できたこと
  • フロントエンドの設計の表層だけでも理解できるようになったこと
  • OAuth2.0 + Open ID Connectの実装を通してより理解が深まったこと
  • iOSの証明書周り完全に理解したこと
  • iOSAndroidアプリ開発で考えるべきことを言語ができたこと
  • Flutterの情報キャッチアップが継続できていること
  • ISUCONで去年の成績を上回れたこと
  • ブログの月1投稿が継続できたこと
  • 職務経歴書をちゃんと書いたこと

何の成果も得られませんでしたって年では無かったなと思えるだけでも良かった。

良くなかったこと・できなかったこと
  • 競プロを一切やらなくなったこと
  • バックエンド周りのキャッチアップができなかったこと
  • クラウド関連の資格取得を先延ばしにしていること
  • 積ん読を増やしたこと
  • 昨年と同じくらい働き過ぎたこと
  • 今後のキャリアが相変わらず迷走していること

メインの仕事がクライアントサイドだったので、バックエンド周りのことはなかなか手が回らなかった。競プロも一切やらなくなってしまった。

昨年同様その日暮らしというか、3ヶ月先の見通しはできても3年、5年先の見通しが立たない。こんな情勢も相まってよりそれが強まった。

在宅ワークで、固定のメンバーでの定常的な会話が続いて、一日一歩も外に出ない日々が続いたらきっとどこかで病むのも無理ないなと思ったりした。

2021年の抱負的な何か

半分以上去年と同じ気がするけど今年も書く。

  • iOS / Android / Reactで個人アプリを作ってみる
  • AWS SA Pro or DevOps Proを取る
  • GCP Professional Cloud Architectを取る
  • TOEICスコア(785)を更新する
  • AtCoderを再開する
  • PASTを受験する
  • ISUCONに出る(開催されれば)
  • アーキテクト業を自信を持って遂行でき、自分の色を出せるようになる
  • エンジニアリングマネージャー業を自信を持って遂行でき、自分の色を出せるようになる
  • 月1ブログ投稿を継続する
  • 3年後、5年後の自分の仕事・人生の具体的なイメージを持つ
  • 健康を維持・推進する

いっぱい掲げて見て、結果半分くらいできる、ってのが気楽でいいんだろうなと思った。フロントエンドお腹いっぱいになったら、またバックエンドに戻ってもいいかなと思ったりした。

まとめ

最近後輩と会話した時に鬼滅の刃の話題になって、

「takamii228さんは僕らにとっての上弦の鬼ですよ、あ、柱か」

???と思って聞いてみると

「やったできぞって思ってもtakamii228さんといろいろ話すうちにまだまだなんだなーって思ってこのシーンの炭治郎の気持ちになります」

https://d2l930y2yx77uc.cloudfront.net/production/uploads/images/22037415/picture_pc_958a7f966b339a01b394979f2c9316df.png

って言われた。

なるほどそんなふうに見られてるんだって思ったと同時に、いやいや俺もまだまだ炭治郎の気分だよって思った。

どんなプロフェッショナルも最初は素人だし、きっとみんなそれぞれに敵わないと思ってる人がいるんだろうなという結論に至った。

こんな世の中だけど、少しでも元気が出るような学びや達成感を得られる2021年にしたい。