2020-01-20

FabricからFirebaseへのマイグレーション

Fabric は 2020 年 3 月 31 日をもって、Firebase に統合されます。

https://get.fabric.io/roadmap

そのため、Fabric で使っていた Beta や Crashlytics を Firebase にマイグレーションをする必要があります。

今回は、iOS と Android で Beta と Crashlytics を Firebase SDK に置き換えた話をします。

Firebase Crashlytics

Fabric の移行フローに沿って、Firebase Console の操作をします。

その後、Firebase Console にある Crashlytics が Fabric と同期されるようになり、クラッシュイベントが表示されるようになります。

ここまでは簡単なのですが、Fabric で使っていた SDK を Firebase Crashlytics SDK に移行する必要があります。

なお、Firebase Crashlytics SDK はまだベータな模様で、公式でちゃんとした導線はまだ出ていないみたいですが、どのみち移行することになりそうなので、今回は SDK も同時に移行しました。

iOS

基本的に ここ を読んでいけばいいのですが、結構ハマりどころが多かったので、その部分を重点的に解説します。

まず、CocoaPods で使われている Podfile の中の pod 'Fabric'pod 'Crashlytics' を取り除き、 pod 'Firebase/Crashlytics' を追加します。

ここでハマったのですが、 pod 'Firebase/Core' が既に入っている場合は、 pod 'Firebase/Core' ではなく pod 'Firebase/Analytics' を入れてください。

その後、Build Phases で dSYM も生成できるようにします。XcodeGen をお使いの場合は、 postBuildScripts にフローを追加するだけでおしまいです。

postBuildScripts:
  - name: Run Crashlytics
    script: ${PODS_ROOT}/FirebaseCrashlytics/run

次にアプリ側のマイグレーションを行います。今回は Swift で解説します。

Crashlytics を使っているソースコードから import Crashlyticsimport FirebaseCrashlytics に変更します。

その後、 let crashlytics = Crashlytics.sharedInstance としていたところは let crashlytics = Crashlytics.crashlytics() に置き換えます。

setUserIdentifiersetUserIDに、 recordErrorrecord と変えていきます。この部分は Firebase の公式ドキュメントを参考にしてください。

全ての置き換えが完了後、一度強制的にクラッシュさせてみて、Firebase Console よりクラッシュイベントが正常に拾えているかどうか確認します。

問題なければおしまいです。

Android

Android も基本的に ここ を読んでいけば大丈夫ですが、一応解説します。

ルートにある build.gradle の repository から maven { url 'https://maven.fabric.io/public' } を削除します。その次に、dependencies に classpath 'io.fabric.tools:gradle:1.31.2' を削除し、classpath 'com.google.firebase:firebase-crashlytics-gradle:17.0.0-beta01' を追加します。

その後、 app の build.gradle の dependencies と plugin に以下を追加します。Fabric で使っていたものは削除してください。

    api "com.google.firebase:firebase-crashlytics:17.0.0-beta01"
    apply plugin: 'com.google.firebase.crashlytics'

ここもハマりどころですが、ドキュメントには firebase-crashlytics しか書いてありませんでしたが、実際には firebase-crashlytics の依存関係として firebase-analytics も読み込まれるみたいです。

また、Android NDK を使っている場合、シンボルのアップロードをしないとクラッシュログの中身が人間に読めない形で表示されてしまうので、ドキュメントに沿って build.gradle に下記のような形で書いておきましょう。

            firebaseCrashlytics {
                nativeSymbolUploadEnabled true
                strippedNativeLibsDir "build/ndklibs/obj"
                unstrippedNativeLibsDir "build/ndklibs/libs"
            }

シンボルのアップロードは ./gradlew app:uploadCrashlyticsSymbolFileRelease のようなタスクを実行してあげる必要があります。CircleCI や Bitrise などの CI で回すと良いでしょう。

追記(2020/01/20): 現在、既に Firebase Crashlytics で Fabric とリンクした場合、クラッシュレポートがアップロード出来ない問題が起きています。新規で作成するか、Firebase 側の対応が終わるまでは旧 Crashlytics SDK をお使い頂くことを推奨します。

次にアプリ側のマイグレーションを行います。今回は Kotlin で解説します。

import が com.google.firebase.crashlytics.FirebaseCrashlytics に変わり、 FirebaseCrashlytics は ContentProvidor より自動起動されるようになったため、 Fabric.with(getContext(), Crashlytics()) は要らなくなりました。

Crashlytics.setUserIdentifierFirebaseCrashlytics.getInstance().setUserId になり、 Crashlytics.logFirebaseCrashlytics.getInstance().log となりました。

log に関しては、Fabric では priority と tag と message を入れる必要がありましたが、Firebase Crashlytics SDK では String に変更になっています。

ただ、これだとログが読みにくいので、Logger で Timber を使っている場合は以下のように書き直しました。

        override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
            FirebaseCrashlytics.getInstance().log("${priority}/${tag}: ${message}")
            t?.let { FirebaseCrashlytics.getInstance().recordException(it) }
        }

これで一安心ですね。

Firebase App Distribution

Fabric Beta は Firebase では App Distribution に生まれ変わりました。

ただ、Fabric Beta とは互換がないので、今回は新規で入れる必要があります。

iOS

プロジェクトのルートで fastlane add_plugin firebase_app_distribution を叩き、 プラグインを追加します。

その後、fastlane の レーン を以下のような形で書きます。

  desc "Deploy Develop Build"
  lane :develop do |options|
    gym(
      scheme: "TestApp",
      configuration: "Debug",
      export_method: "development",
      include_bitcode: false,
    )
    # Upload to Firebase App Distribution
    firebase_app_distribution(
      app: "FIREBASE_APP_ID",
      groups: "YOUR_GROUP_NAME",
      release_notes: last_git_commit[:message],
      firebase_cli_path: `which firebase`.strip()
    )
  end

app には Firebase プロジェクトの App Id が必要となります。Console から確認しておきましょう。

groups は テスターのグループ名を指定します。

その後、CircleCI や Bitrise で回す際ですが、 firebase-cli を入れるのをお忘れなく。npm でも HomeBrew でも入ります。また、環境変数に FIREBASE_TOKEN を入れる必要があります。手元のローカルから firebase login:ci を叩き、トークンを発行しておきましょう。

なお、ここでハマったのですが、 Firebase App Distribution を使うには一度 Console のほうで有効化する必要がありますのでお気をつけください。

Android

Android の場合は GitHub Actions を使った方法で説明していきます。

Actions では wzieba/Firebase-Distribution-Github-Action を使うのが一番近道です。

今回は以下のようなフローを追加しました。

- name: Build
  run: ./gradlew assembleBillingDebug
- name: Deploy Firebase App Distribution
  uses: wzieba/Firebase-Distribution-Github-[email protected]
  with:
    appId: YOUR_FIREBASE_APP_ID
    token: ${{secrets.FIREBASE_TOKEN}}
    groups: YOUR_GROUP_NAME
    file: app/build/outputs/apk/debug/app-billing-debug.apk

なお、 token には FIREBASE_TOKEN を入れる必要があります。手元のローカルから firebase login:ci を叩き、トークンを発行しておきましょう。

Firebase App Distribution を使うには一度 Console のほうで有効化する必要がありますのでお気をつけください。


これで Crashlytics と Beta を Firebase Crashytics と Firebase App Distribution に移行できました。

インターネットを探してもなかなかまとまった記事がなかったので今回解説していきましたが、誤字脱字等があれば @yaminoma_tw まで教えてください。