flutterでFirebase App Distributionを利用してアプリを配布する

f:id:takkumattsu:20210208130449p:plain
こんにちは、 id:takkumattsu です!

ここ最近flutterの案件が増えてきていて、コベリンでもモバイルの仕事の半分くらいはflutterをやっています。

と言うことで今日はflutterでアプリを配布する方法について書いていきたいと思います。

コードは https://github.com/TakkuMattsu/flutter_firebase_app_distribution_sample においてあります。

準備

始める前に以下を済ませておいてください。

  • iOSのアプリのBundle Identifierの作成
  • iOS配布用(AdHock)の証明書
Bundle Identifier 証明書

Firebaseにプロジェクトを追加

|

Firebase consoleにアクセスして新しいプロジェクトを作成します。

iOSとAndroidのプロジェクト作成します。

image image

リリースとモニタリングの中にあるApp Distributionを選択します。

f:id:takkumattsu:20210208120943p:plain

iOSとAndroid共に開始をしておきます。
これをやっておこないと配布時にエラーになります。

配布用のグループを追加

これはやらなくてもいいですが運用的に開発メンバーだけに配布、外部テスターだけに配布みたいなことをやりたい場合が多いと思うので自分の場合はグループの機能を使っています。

テスターとグループタブのグループの追加を押し

image

グループの名前はfastlaneで指定するエイリアスになるので英数字で記載するのをお勧めします

image

あとは適宜テスターを追加してください。

Bundlerでfastlane追加

Firebase consoleでの作業はおしまいで、次は配布のためのfastlaneの用意をしていきます。

まずrootの階層に以下のGemfileを追加します

source 'https://rubygems.org'
gem "fastlane"
gem "cocoapods"

plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
eval_gemfile(plugins_path) if File.exist?(plugins_path)

必要なgemをインストールします

# 個人的には以下のようにしてインストールする場所をしていして.gitignoreしています
# bundle config path --local 'vendor/bundle'
bundle install

fastlaneの準備

fastlaneのFastfileは以下のように配置します

  • fastlane/Fastfile
    • root階層でfastlane叩くFastfile
  • ios/fastlane/Fastfile
    • iOSに関するlaneを書くFastfile
  • android/fastlane/Fastfile
    • Androidに関するlaneを書くFastfile

fastlane/Fastfile

skip_docs
# トークンの取得は firebase login:ci
FIREBASE_CLI_TOKEN=""

import "../android/fastlane/Fastfile"
import "../ios/fastlane/Fastfile"

FIREBASE_CLI_TOKENfirebase login:ciを使って取得します

ひとまずios/fastlane/Fastfileandroid/fastlane/Fastfileは空のファイルをおいておきます。

fastlaneで利用するpluginをインストール

fastlane-plugin-firebase_app_distribution以外は使っても使わなくても大丈夫ですが、自分は便利なので使っています。

# 以下プラグインをインストール
bundle exec fastlane add_plugin fastlane-plugin-firebase_app_distribution
bundle exec fastlane add_plugin fastlane-plugin-badge
bundle exec fastlane add_plugin fastlane-plugin-flutter_version

この状態でbundle exec fastlane listを叩くと以下のようになると思います

$ bundle exec fastlane list
[] 🚀
+-------------------------------------------+---------+-----------------------------------------------------------+
|                                                  Used plugins                                                   |
+-------------------------------------------+---------+-----------------------------------------------------------+
| Plugin                                    | Version | Action                                                    |
+-------------------------------------------+---------+-----------------------------------------------------------+
| fastlane-plugin-firebase_app_distribution | 0.2.5   | firebase_app_distribution_login firebase_app_distribution |
| fastlane-plugin-badge                     | 1.4.0   | add_badge                                                 |
| fastlane-plugin-flutter_version           | 1.0.1   | flutter_version                                           |
+-------------------------------------------+---------+-----------------------------------------------------------+

[13:01:56]: Available lanes:
[13:01:56]: Execute using `fastlane [lane_name]`

iOSのFastfile

# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
#     https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
#     https://docs.fastlane.tools/plugins/available-plugins
#

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane

default_platform(:ios)

platform :ios do

  $nowDate = DateTime.now
  
  desc "iOS Firebase App Distribution"
  lane :firebase_app_distribuition do
    # flutterの前処理
    sh("flutter", "clean")
    sh("flutter","pub", "get")
    sh("flutter", "build", "ios", "--release")
    # 配布用にアイコンを変えたりバージョンを変えたり
    set_debug_info
    # ビルド
    build_app(
      workspace: "ios/Runner.xcworkspace",
      export_options: {
        method: "ad-hoc",
        provisioningProfiles: {
          "!!!ここは適宜BundleIdentifierに変えてください!!!": "!!!ここは適宜プロビジョニングの名前に変えてください!!!"
        }
      },
      clean: true,
      export_xcargs: "-allowProvisioningUpdates",
      output_name: "sample.ipa",
      output_directory: "build/ios/"
    )
    # canagelog作成
    sh('git log -n 1 > ./latest_commit_log.txt')
    sh('cat ./latest_commit_log.txt')
    # リリースノート
    changelog = ENV['PWD'] + "/fastlane/latest_commit_log.txt"

    # 配布
    firebase_app_distribution(
      app: "!!!ここは適宜かえてください!!!",
      ipa_path: "build/ios/sample.ipa",
      groups: "developer",
      firebase_cli_token: FIREBASE_CLI_TOKEN,
      release_notes_file: changelog)
    # 変更差し戻し
    sh("git", "checkout", "../ios")
    sh("rm", "./latest_commit_log.txt")
  end

  # 配布用にアイコンを変えたり、バージョンをいじったり
  def set_debug_info
    # バージョン変更
    version_change_for_timestamp
    # アプリアイコン変更
    original_short_version = get_version_number(xcodeproj: "ios/Runner.xcodeproj")
      add_badge(
        dark: true,
        grayscale: true,
        shield: original_short_version + "-" + $nowDate.strftime("%Y%m%d%H%M") + "-blue"
      )
  end

  # タイムスタンプからビルドバージョンを作成
  def version_change_for_timestamp
    path = "ios/Runner/Info.plist"
    # CFBundleVersionを日付ベースに書き換え
    set_info_plist_value(
      path: path,
      key: "CFBundleVersion",
      value: $nowDate.strftime("%y%m%d.%H%M")
    )
  end
end

AndroidのFastfile

# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
#     https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
#     https://docs.fastlane.tools/plugins/available-plugins
#

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane

default_platform(:android)

platform :android do

  $nowDate = DateTime.now

  desc "Android Firebase App Distribution"
  lane :firebase_app_distribuition
    build_number = $nowDate.strftime("%m%d%H%M")
    sh( "flutter","clean" )
    sh( "flutter","pub", "get")
    sh( "flutter","build","apk","--release", "--build-number", build_number)
    # バージョンの取得に https://github.com/Jems22/fastlane-plugin-get-version-name を利用しようと思ったが、flutterでは
    # local.propertiesのflutter.versionNameが利用されるため取得できなかった
    # なので https://github.com/tianhaoz95/fastlane-plugin-flutter_version を利用
    add_badge(
        dark: true,
        grayscale: true,
        shield: flutter_version(pubspec_location: "./pubspec.yaml")["version_name"] + "-" + $nowDate.strftime("%Y%m%d%H%M") + "-blue",
        glob: "/android/app/src/main/res/*/ic_launcher.png"
      )
    # canagelog作成
    sh('git log -n 1 > ./latest_commit_log.txt')
    sh('cat ./latest_commit_log.txt')
    # リリースノート
    changelog = ENV['PWD'] + "/fastlane/latest_commit_log.txt"

    # 配布
    firebase_app_distribution(
      apk_path: "build/app/outputs/flutter-apk/!!ここは適宜変えてください!!.apk",
      app: "!!!ここは適宜かえてください!!!",
      firebase_cli_token: FIREBASE_CLI_TOKEN,
      groups: "developer",
      release_notes_file: changelog
    )
    # 変更差し戻し
    sh("git", "checkout", "../android")
    sh("rm", "./latest_commit_log.txt")
  end
end

最後に

ひとまずこれで配布できるようになるかと思います。
flavorを分けて配布する方法は次回書きたいと思います。