Android
GitHub
iOS
Crashlytics
Firebase

Firebase CrashlyticsとGitHub Issueを連携した

概要

iOS・AndroidアプリでFirebase Crashlyticsを使ったクラッシュレポートを使っており、新しいクラッシュが発生したらGitHubにIssueを自動で起票するようにしました。

仕組み

Cloud Functions for FirebaseでCrashlyticsのイベントをフック、GitHubのWebAPIを使ってIssueを起票する

GitHub Issue Creator

すでに要件を満たすスクリプトを公開されている方がいらっしゃいました。(圧倒的感謝)
こちらのReadmeの通りにすれば導入可能です。
https://github.com/kevalpatel2106/github-issue-cloud-function

留意点

Firebaseの課金プランがBlazeである必要がある

このプランでなければCloud Functionsから外部APIを叩けないため
※GitHub Issue CreatorのReadmeにも書かれている

独自の要件

iOSとAndroidで起票するリポジトリ先を変えたい

公開されているスクリプトはIssueを起票するリポジトリは1つしか対応していません。
今回の要件ではiOSとAndroidで起票するリポジトリを別にしたいと思いました。
そこでスクリプトと環境変数を少し変更しました

環境変数

$ firebase functions:config:set github.base_url="https://api.github.com" github.token="xxxxxxxx" issue.title="[Crashlytics]" issue.body="" issue.lable="Bug_Public" repo.owner="owner" repo.ios_repo_name="iOS" repo.android_repo_name="android"

※環境変数の変更後はfunctionの再デプロイが必要でした

index.js

appPlatformという変数に"ios" or "android"が代入されるので、そこで向き先を設定

index.js
exports.postOnNewIssue = functions.crashlytics.issue().onNew((issue) => {

  var issueId = issue.issueId;
  var issueTitle = issue.issueTitle;

  var appId= issue.appInfo ? issue.appInfo.appId: "";
  var appName = issue.appInfo ? issue.appInfo.appName : "";
  var appPlatform = issue.appInfo ? issue.appInfo.appPlatform : "";
  var latestAppVersion = issue.appInfo ? issue.appInfo.latestAppVersion : "";

  var repoName = "";
  if (appPlatform == "ios") {
    repoName = functions.config().repo.ios_repo_name;
  } else {
    repoName = functions.config().repo.android_repo_name;
  }

  // Prepare the issue text.
  var title = `${functions.config().issue.title} - ${issueTitle} (${issueId})` ;
  var message = `Crash report : [Firebase Console Link](https://console.firebase.google.com/u/0/project/${process.env.GCLOUD_PROJECT}/crashlytics/app/${appPlatform}:${appId}/issues/${issueId})

  ### Application Info:\n
  **Application name**: ${appName}(${appId}) 
  **Version**: ${latestAppVersion} on ${appPlatform}`;

  return createIssue(title, message, repoName).then(() => {
    return console.log(`Posted new issue ${issueId} successfully to GitHub`);
  });
});

const createIssue = (issueTitle, issueMessage, repoName) => {
  // See https://developer.github.com/v3/issues/#create-an-issue on how
  // to customize the message payload
  var issueReq = rp({
    method: 'POST',
    uri: functions.config().github.base_url + '/repos/' + functions.config().repo.owner + '/' +  repoName + '/issues',
  qs: {
        access_token: functions.config().github.token // -> uri + '?access_token=xxxxx%20xxxxx'
    },
    body: {
      title: issueTitle,
    body: issueMessage,
    labels: [
    functions.config().issue.lable
    ]
    },
  headers: {
    "User-Agent": "Firebase-Cloud-Functions",
        "Accept" : "application/vnd.github.v3+json",
    "Content-Type" : "application/json"
    },
    json: true,
  });

  console.log(issueReq);
  return issueReq;
};

参照

https://github.com/koishi/github-issue-cloud-function/blob/work/functions/index.js

結果

このようにIssueが作られるようになりました😃

Issueリスト

image.png

Issue詳細

image.png

おまけ(今回一番はまった問題)

Cloud Functions for FirebaseのDeployでエラー発生

firebase deployするとエラー😢

名称未設定.png

色んなことを調べましたが、原因が全く分からず、対処方法も不明でした。
結果、サポートに連絡して何度かやりとりすることで発生していたエラーを解消してもらえました。
原因不明のエラーが発生しましたら、Firebase Status Dashboard( https://status.firebase.google.com/ )を確認するか、サポートへの問い合わせをおすすめします。
今回のケースではCloud Functions全体の障害も起きていたのですが、障害が収束されてからもエラーが変わらず、特定のプロジェクトのみで起きる問題でした。