Slide 1

Slide 1 text

アプリのメンテナンス画面・ 強制アップデートを再考する m.coder

Slide 2

Slide 2 text

1 自己紹介 m.coder (@_m_coder) フラー株式会社所属 ( 2021/01〜 ) Androidエンジニア歴3年

Slide 3

Slide 3 text

We are Hiring!

Slide 4

Slide 4 text

スマホアプリの 自動アップデート、 ONにしてますか?

Slide 5

Slide 5 text

不具合が怖い 自分で管理したい 以前使えていた機能が使えなくなったetc... (ユーザー側の視点で) 自動アップデートしたくない理由

Slide 6

Slide 6 text

アプリを出す側としては、 最新版を使って欲しい…

Slide 7

Slide 7 text

→強制アップデート

Slide 8

Slide 8 text

(アプリ提供側の視点で) 強制アップデートさせたい理由 API側のデータ構造が変わる 追加機能をどうしても使って欲しい 不具合・脆弱性の解消

Slide 9

Slide 9 text

API側のデータ構造が変わる 追加機能をどうしても使って欲しい 不具合・脆弱性の解消 →サーバー側のメンテナンスを行う可能性が高い (アプリ提供側の視点で) 強制アップデートさせたい理由

Slide 10

Slide 10 text

メンテナンス画面が欲しい

Slide 11

Slide 11 text

メンテナンス画面 いつ出す? 強制アプデで ユーザー離脱 怖いな 手軽にアップデート させる方法ないかな どう実装する? 考えることがいっぱいで 後回しになりがち…

Slide 12

Slide 12 text

メンテナンス画面と 強制アップデートを いい感じに実現する方法を 改めて考えたい 【本スライドのテーマ】

Slide 13

Slide 13 text

※諸説あります いい方法知っている方は 教えて下さい🙏

Slide 14

Slide 14 text

【対象】 小〜中規模なサービスや 個人開発 メンテナンス専用のサーバーを立てられるほどじゃないけど、 メンテナンス画面や強制アップデートは実装したい

Slide 15

Slide 15 text

説明すること 以下のサービスを利用したメンテナンス画面・強制アッ プデートの実現方法とメリット・デメリット APIのレスポンスから判断する Firebase Remote Configを使う Cloud Firestoreを使う In-app updatesを使う(強制アップデート)

Slide 16

Slide 16 text

説明しないこと 取り上げるサービス (Firebase Remote ConfigやCloud Firestore) の細かい使い方や解説

Slide 17

Slide 17 text

観点 即時性 カスタマイズ性  (メンテ・リリースにすぐ反応して欲しい)  (メンテナンス時間とか説明とか表示したい)

Slide 18

Slide 18 text

APIのレスポンスから判断する

Slide 19

Slide 19 text

サーバー側と 「メンテナンスの時は503を返す」など取り決めをして、 該当のレスポンスが返ってきた時はメンテナンス画面を表示する APIのレスポンスから判断する 503 (メンテナンス画面)

Slide 20

Slide 20 text

APIのレスポンスヘッダーにアプリの必須バージョンを 埋め込んでおいてもらい、アプリ側でパースする アップデート 通知 APIのレスポンスから判断する (強制アップデート) X-Require-Build- Version: 1.2.0

Slide 21

Slide 21 text

メリット 実装の負荷が一番少ない APIアクセス時に判断できるので即時性がある

Slide 22

Slide 22 text

デメリット メンテ時間や文言等を取得できないのでカスタマ イズ性が低い メンテ時間や文言などの情報を持った静的なJSONファイルをサ ーバーに置いておく WebViewでメンテ用のWebページに飛ばす 【回避策】 1. 2.

Slide 23

Slide 23 text

Firebase Remote Configを使う

Slide 24

Slide 24 text

Firebase Remote Config サーバーやAPIを用意しなくても アプリに動的な値を読み込ませられるサービス SharedPreferencesのようにKey-Value形式で値をフェッチ 可能 A/BテストやAPIを立てるまでもないパラメータのフェッチ などに使われることが多い

Slide 25

Slide 25 text

Firebase Remote Configの特徴 指定条件(日時・プラットフォーム・ビルド番号 など)によってパラメータを出し分けられる パラメータはJSON形式で記述 無料

Slide 26

Slide 26 text

Firebase Remote Config利用方法 2021/10/21 19:00から21:00までメンテナンス を行いたい 【例】

Slide 27

Slide 27 text

Firebase Remote Config利用方法 適用条件を指定する(Firebase コンソールの例)

Slide 28

Slide 28 text

Firebase Remote Config利用方法 指定条件時に反映させたいJSONを指定する

Slide 29

Slide 29 text

Firebase Remote Config利用方法 メンテナンス終了時刻(21:00-)のJSONも同じ様に指定する

Slide 30

Slide 30 text

Firebase Remote Config利用方法 メンテナンス終了時刻(21:00-)のJSONも同じ様に指定する

Slide 31

Slide 31 text

Firebase Remote Config利用方法 ViewのonResume時やAPIアクセス前などにRemoteConfigの値をフ ェッチする

Slide 32

Slide 32 text

Firebase Remote Config利用方法 ViewのonResume時やAPIアクセス前などにRemoteConfigの値をフ ェッチする

Slide 33

Slide 33 text

メリット 時刻やバージョン、プラットフォームなどの条件 でJSONの出し分けが可能なため、カスタマイズ性 が高い

Slide 34

Slide 34 text

デメリット フェッチ間隔に制限があるため、即時性に難点が ある

Slide 35

Slide 35 text

Remote Configの注意点

Slide 36

Slide 36 text

Remote Configの注意点 →短時間での多数のフェッチは想定されていない

Slide 37

Slide 37 text

仮にフェッチ間隔を60(1分)に設定したとしても、 状態の反映に最長で1分間のラグがあると想定する必 要がある Remote Configの注意点

Slide 38

Slide 38 text

Remote Configの注意点 →サーバーのメンテナンス開始時刻よりも少し早くメン テナンスモードに設定するなどの工夫が必要 仮にフェッチ間隔を60(1分)に設定したとしても、 状態の反映に最長で1分間のラグがあると想定する必 要がある

Slide 39

Slide 39 text

Cloud Firestoreを使う

Slide 40

Slide 40 text

Cloud Firestoreの特徴 NoSQLなクラウドデータベース ※ドキュメントの読み取り 50,000/日  ドキュメントの書き込み 20,000/日 SnapShotListenerというものを用いてリアルタイ ム通信が可能 無料通信枠あり

Slide 41

Slide 41 text

Cloud Firestore利用方法 Firestoreのドキュメントにパラメータを指定する

Slide 42

Slide 42 text

Cloud Firestore利用方法 ApplicationクラスやMainActivityのonResume時などに SnapShotListenerを設定してリアルタイム監視する

Slide 43

Slide 43 text

Cloud Firestore利用方法 ApplicationクラスやMainActivityのonResume時などに SnapShotListenerを設定してリアルタイム監視する 値はMap形式で流れてくる

Slide 44

Slide 44 text

Cloud Firestore利用方法 なぜ「ApplicationクラスやMainActivityのonResume時」?

Slide 45

Slide 45 text

Cloud Firestore利用方法 なぜ「ApplicationクラスやMainActivityのonResume時」? →SnapShotListenerは一度設定すれば Detach するまで値が流れ続 ける

Slide 46

Slide 46 text

Cloud Firestore利用方法 なぜ「ApplicationクラスやMainActivityのonResume時」? →SnapShotListenerは一度設定すれば Detach するまで値が流れ続 ける →アプリがフォアグラウンド時に Listener を設定して、アプリがバ ックグラウンドに移行した時に Detach することで、アプリ起動中 は常時値を監視できる

Slide 47

Slide 47 text

Cloud Firestore利用方法 なぜ「ApplicationクラスやMainActivityのonResume時」? →SnapShotListenerは一度設定すれば Detach するまで値が流れ続 ける →アプリがフォアグラウンド時に Listener を設定して、アプリがバ ックグラウンドに移行した時に Detach することで、アプリ起動中 は常時値を監視できる →アプリのライフサイクルに合わせられるApplicationクラスや MainActivity(SingleActivity構成の場合)がよさそう

Slide 48

Slide 48 text

メリット 値がリアルタイムで反映されるので即時性がある →アプリ起動中にメンテナンスフラグが立ったら 即メンテナンス画面を表示させることも可能 パラメータのもたせ方は自由なのでカスタマイズ 性もある

Slide 49

Slide 49 text

デメリット ユーザーの数だけSnapShotListenerを登録するの で、ユーザー数が増えた時の負荷を考慮する必要 がある ライフサイクルを考慮して実装しないと、無限に Listenerを生やしてしまい通信量が爆発する可能 性も…

Slide 50

Slide 50 text

In-app updatesを使って 強制アップデートを実現する 番外編

Slide 51

Slide 51 text

Play Core ライブラリ で提供されるアプリ内 アップデート機能 Play ストアの情報を 取得してアップデート の有無を判定 In-app updates ※Google公式より引用

Slide 52

Slide 52 text

ユーザーが任意でアップデートを選択可能な flexible アップ デートと、強制でアップデートさせる immediate アップデー トが用意されている In-app updates ※Google公式より引用

Slide 53

Slide 53 text

In-app updatesの特徴 アップデートの優先度を設定できる(普段のアップデート は flexible、必須アップデートは immediate などの出し分 けが可能) アップデート配信からの経過時間が取得できるため、配信 から数日後にアップデートしていなかったユーザーにはア ップデート通知を出すなどの調整も可能

Slide 54

Slide 54 text

In-app updatesの利用例

Slide 55

Slide 55 text

In-app updatesの利用例

Slide 56

Slide 56 text

In-app updatesの利用例 アップデートの存在チェックを行う

Slide 57

Slide 57 text

In-app updatesの利用例 →versionCodeで判断

Slide 58

Slide 58 text

In-app updatesの利用例 →startActivityForResult的なもの

Slide 59

Slide 59 text

参考 Google公式 アプリ内アップデート https://developer.android.com/guide/playcore/in-app- updates DroidKaigi 2020 Lite アプリのアップデート浸透率を上げろ! ~in-app updatesを 実戦投入して見えてきたもの~ / masaibar https://youtu.be/u-zUIIe8IfA

Slide 60

Slide 60 text

In-app updatesの注意点 アップデートの優先度の設定は、今のところGoogle Play Developer APIを使用しないとできない(Play Consoleから直接 設定できない) ストアにリリースされたものと同じパッケージ名・同じキーで 署名したバイナリでのみテストができる(flavorを分けていたり する場合は要注意) immediate アップデートは実は強制じゃない(バックキーでア ップデート画面を抜けられる)

Slide 61

Slide 61 text

In-app updatesの注意点 アップデートの優先度の設定は、今のところGoogle Play Developer APIを使用しないとできない(Play Consoleから直接 設定できない) ストアにリリースされたものと同じパッケージ名・同じキーで 署名したバイナリでのみテストができる(flavorを分けていたり する場合は要注意) immediate アップデートは実は強制じゃない(バックキーでア ップデート画面を抜けられる)

Slide 62

Slide 62 text

In-app updatesの注意点 アップデートの優先度の設定は、今のところGoogle Play Developer APIを使用しないとできない(Play Consoleから直接 設定できない) ストアにリリースされたものと同じパッケージ名・同じキーで 署名したバイナリでのみテストができる(flavorを分けていたり する場合は要注意) immediate アップデートは実は強制じゃない(バックキーでア ップデート画面を抜けられる)

Slide 63

Slide 63 text

In-app updatesの注意点 アップデートの優先度の設定は、今のところGoogle Play Developer APIを使用しないとできない(Play Consoleから直接 設定できない) ストアにリリースされたものと同じパッケージ名・同じキーで 署名したバイナリでのみテストができる(flavorを分けていたり する場合は要注意) immediate アップデートは実は強制じゃない(バックキーでア ップデート画面を抜けられる)

Slide 64

Slide 64 text

In-app updatesのメリット Playストアと連携できる(手動で必須バージョンなどを管 理しなくていい) デフォルトで immediate と flexible が用意されているので 柔軟に対応できる ユーザーがストアに遷移する手間を省ける(ユーザー離脱 を防げるのでは?)

Slide 65

Slide 65 text

In-app updatesのデメリット Android版しか対応できない アップデートを拒否された場合やアップデート中にタスク キルした場合のハンドリング対応など、実装コストがそれ なりに高い ノウハウがまだ少なくハマりポイントが大いにある(あり そう)

Slide 66

Slide 66 text

In-app updatesでハマったポイント バージョンの低いバイナリを用意しているのに UPDATE_NOT_AVAILABLE( 更新なし) しか返ってこない

Slide 67

Slide 67 text

In-app updatesでハマったポイント →UPDATE_AVAILABLE になる条件は Play ストアに 「更新」と表示されていること バージョンの低いバイナリを用意しているのに UPDATE_NOT_AVAILABLE( 更新なし) しか返ってこない

Slide 68

Slide 68 text

In-app updatesでハマったポイント bundletool などでapk をインストールすると バージョンを下げていても「開く」表示になってしまった

Slide 69

Slide 69 text

In-app updatesでハマったポイント bundletool などでapk をインストールすると バージョンを下げていても「開く」表示になってしまった →テストの時はPlay ストアの内部テスト版などの利用が 必要そう

Slide 70

Slide 70 text

In-app updatesでハマったポイント 内部テスト版を公開しても「開く」のままになっている

Slide 71

Slide 71 text

In-app updatesでハマったポイント 内部テスト版を公開しても「開く」のままになっている →Play ストアアプリのキャッシュクリアで解消

Slide 72

Slide 72 text

In-app updatesでハマったポイント デバイスに複数アカウントを登録している場合も要注意

Slide 73

Slide 73 text

In-app updatesでハマったポイント デバイスに複数アカウントを登録している場合も要注意 アカウントA :内部テスター登録済み アカウントB :非内部テスター の状態で内部テスト版を公開

Slide 74

Slide 74 text

In-app updatesでハマったポイント デバイスに複数アカウントを登録している場合も要注意 アカウントA :内部テスター登録済み アカウントB :非内部テスター の状態で内部テスト版を公開 →アプリで非内部テスターと判断されたのか「更新なし」 と判定されていた

Slide 75

Slide 75 text

まとめ

Slide 76

Slide 76 text

まとめ REST APIならAPIレスポンスで判断、サーバーレスなら Firestoreあたりがやりやすそう? In-app updatesはハマりポイントに気をつければユーザ ー体験はよさそう メリデメに気をつけながら自分のサービスに合ったメン テナンス画面・強制アップデートを実装しよう

Slide 77

Slide 77 text

おしまい