前人未踏の領域へ Androidアプリ開発編

Androidアプリ開発に関する調査メモ置き場。古い記事にはアプリ以外も含まれます。

Firebase Invitesを使う [Android]

そしてDeprecatedへ

Firebaseのサポートからメールが来ていたので報告していたバグが直ったかなーと思ったら Deprecated の案内だった。

https://firebase.google.com/docs/invites/deprecation

今後は普通のACTION_SENDのシェアと Dynamic Link 使えとのことだそうな。俺の調査時間を返せ。

↓↓↓↓↓ 以下はDeprecatedになる前の調査記事 ↓↓↓↓↓

現状について

Firebase Invitesの最新のAndroidライブラリ16.0.6では 連絡先一覧画面のActivityからメッセージを表示する(電話番号送信時の課金警告とメール送信後の完了メッセージ)際に、Oreo以降のバージョンだとパーミッションエラーが発生してActivityが落ちてしまうのでこの問題をFirebaseに報告しつつ採用は見送り中。

(追記) 12/4にバグレポートの担当者から問題が再現したので対応中との連絡あり。連絡を待つことにする。

お題

Firebase Invitesを使ってユーザーがアプリから友達を招待できるようにしたい。

環境

  • Android Studio 3.3 Beta4
  • com.android.tools.build.gradle:3.2.1
  • kotlin-gradle-plugin:1.3.10
  • firebase-plugins:1.1.5
  • google-services:4.2.0
  • firebase-core:16.0.4
  • firebase-invites:16.0.4

実装

onClickListenerなどに書く

val intent =
    AppInviteInvitation.IntentBuilder("ご案内")
        .setMessage("このアプリやろうぜ")
        .setEmailSubject("アプリに招待します")
        .setEmailHtmlContent(
            "<html><body>%%APPINVITE_LINK_PLACEHOLDER%%</body></html>"
        )
        .setGoogleAnalyticsTrackingId(getString(R.string.ga_trackingId))      //GoogleAnalytics
        .setDeepLink(Uri.parse("https://hogehoge.com/items/12345"))         //DeepLinkは現在未使用だが無いとSMSのURLが500エラーになるので仮当て
        .build()

startActivityForResult(
    intent,
    REQUEST_INVITE
)

動作

  • startActivityするとcom.google.android.gms.appinvite.ACTION_APP_INVITEアクションに対応するcom.google.android.gms..appinvite.AppInviteActivityが起動する

トラブルシューティング

SMSが送信されない
  • SHA1, SHA256登録後にgoogle-services.jsonを取り直していない(KeyStoreごとにclient_idが異なるようなので注意)
SMSを選択すると招待画面が落ちる(未解決)
  • Android 8.0以降か
  • Permissionの問題
  • android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@3b3fae7 -- permission denied for window type 2003 とか発生して落ちる
SMSのリンク先が500エラーになる

setDeepLinkを記述しないと発生する。nullをセットすると落ちる。使わなくても何かしらそれっぽいURLを書いておく。

メールが送信されない
  • ドキュメントに記載がないが、setEmailSubject setEmailHtmlContent を使わないと送信されない。
onActivityResultが2回呼ばれる
  • FragmentからStartActivityForResultしていて、MainActivity内でFragmentのonActivityResultを呼んでいたために発生
    厳密にはrequestCodeが異なるので合致するRequestCodeのみ扱うことで対応。
onActivityResultが resultCode=3になある
  • 送信に失敗している
  • Firebase ConsoleにSHA1を登録していない(releaseとstagingでKeyStoreが異なる場合などで設定忘れに注意)
  • Firebase ConsoleにSHA256を登録していない(Dynamic Linkの生成に必要)
onActivityResultが常に resultCode=0(RESULT_CANCELED) になる
  • 「SMSを選択すると招待画面が落ちる」と関連
  • 自分のアプリに戻る前にAppInviteActivityが落ちている
  • 送信完了メッセージをSnackBarで表示しようとして落ちる
  • 完了通知時に落ちるので送信はされる(正しく書けていれば)
firebase-core:16.0.5にするとビルドエラーになる

依存関係の問題。 修正版がリリースされているが、よく分からない。dex絡み。

Release Notes  |  Google Play services  |  Google Developers

プロジェクトのbuild.gradleにVersion Matcher Pluginを入れたら動くにようになった気がする

apply plugin: 'com.google.android.gms.strict-version-matcher-plugin'
classpath 'com.google.android.gms:strict-version-matcher-plugin:1.0.2'
  • Clean Projectしてから再ビルドが必要。

まとめ

  • ドキュメント通りには動かない
  • メソッドの使用有無で送信されたりされなかったりがある
  • SMS送信の際にDynamic Linkが自動生成されるので
    AppsFlyerなどの他のDynamic Linkツールと組み合わせて使うには妥協が必要
  • 送信されない理由の説明がないので原因が特定しにくい
  • 結構バグっぽい挙動も多くて手強い

参考

https://firebase.google.com/docs/invites/android?hl=ja#header_2