ディープリンクの実現方式(廃止)
Status: Superseded
Firebase Dynamic Linksの廃止が公式のページでアナウンスされました。そのため、以下のDecision Recordで実現方式を再検討しました。
要約
ディープリンクの実現方式を複数の方式で議論し、導入するメリットが大きいFirebase Dynamic Linksを採用します。
コンテキスト
ディープリンクを実現する方式は、次の3つの方式から選択します。
- OSの機能(Universal Links、Android App Links)を直接利用する
- FirebaseのDynamic Linksを利用する
- カスタムURLスキームを利用する
用語は以下のとおりです。
用語 | 意味 | 備考 |
---|---|---|
ディープリンク | URLに紐付いたモバイルアプリケーションを起動する機能 | |
ディープリンクURL | ユーザが開くURLで、OSがドメインとの関連を検証するときに利用するURLです。OSの検証が成功するとアプリケーションに渡されます。 | Dynamic Linksではパラメータ部分にコンテンツリンクURLなどを保持します。 |
コンテンツリンクURL | アプリで表示したいコンテンツをあらわすURLです。(OSの機能だけの場合はディープリンクURLと同じです) | Dynamic Linksではアプリと関連付けていないドメインのURLも渡すことができます。 |
カスタムURLスキーム | mailto: のようにスキームに任意のプレフィックスを指定したURL | |
App Links | AndroidがOSの機能としてサポートしているディープリンク | Android App Links |
Universal Links | iOSがOSの機能としてサポートしているディープリンク | iOS Universal Link |
Dynamic Links | App Links、Universal Linksを拡張したFirebaseの機能 | カスタムURLスキームは対象外 |
議論
ディープリンクの3つの実現方式のうち、カスタムURLスキームには回避できないセキュリティのリスク1があるため、採用は見送りました。
Dynamic LinksとOSの機能を直接利用する場合の違いは以下のとおりです。
凡例 | 内容 |
---|---|
○ | 対応不要 |
△ | 軽微な対応が必要 |
☓ | 対応が難しい |
観点 | Dynamic Links | OSの機能 |
---|---|---|
アプリへの導線 | ○ | ☓2 |
アプリケーションの実装 | △ | ☓3 |
セキュリティ | △ | ○ |
Dynamic LinksはOSの機能と比較すると、アプリへの導線をサポートしている分、セキュリティの対応が必要になります。 一方でインストールしていないユーザへの導線のためにウェブサイトを構築する作業が短縮されます。
アプリへの導線
OSの機能をそのまま利用すると、URLに関連付けられたアプリケーションがインストールされていない場合は、ウェブサイトと判断されてブラウザでアクセスしてしまいます。 そのため、アプリケーションをインストールしていないユーザ向けに、導線となるウェブサイトを用意する必要があります。
Dynamic Linksでは、未インストールのユーザに対する導線が用意できるので、ウェブサイトを持たないサービスでも簡単にディープリンクを導入できます。
アプリケーションの実装
ディープリンクURLをReact Nativeで受け取る場合は次のライブラリが利用できます。
- Dynamic Linksを利用する場合はReact Native FirebaseとReact Native Linking(併用可能)
- OSの機能はReact Native Linking
Dynamic Linksを利用する場合は、どちらかのAPIを利用すれば実装できます。ただし、下記の点を考慮しアプリ起動時にはPlatformを判定して呼び分けます。
- React Native FirebaseにはiOSで起動時間が短いと読み取れないissueがあります。そのためReact Native Linkingを利用してディープリンクURLを取得します。
- ディープリンクURLに含まれるコンテンツリンクURLを取得するためにresolveLinkを利用します。
- React Native LinkingにはAndroidでディープリンクのURLを読み取れないというissueがあります。そのためReact Native Firebaseを利用してコンテンツリンクURLを取得します。
OSの機能を直接利用する場合(Dynamic Linksを利用しない場合)、AndroidでLinkingが読み取れないissueの原因の調査が必要です。
セキュリティ
App Links、Universal Linksは、ドメインに配置されたファイルを利用して「アプリケーションとURL(ドメイン)の所有者が同じであること」をOSが検証しています。そのため、カスタムURLスキームで問題となるような、他のアプリに情報が意図せず共有されることはありません。
iOSでの意図しない共有
Dynamic Linksではアプリをインストールしていないユーザがディープリンクを開いたとき、初回起動時にURLを読み取る仕組みがあります。 この仕組みにより、OSの機能を拡張して、アプリケーションの初回起動時にディープリンクを読み取ることができます。
この拡張機能を利用すると、iOSでは初回起動時にクリップボードを利用してディープリンクを読み取ります。 一方で、iOSのペーストボードの使用を無効に設定しても、初回起動時に読み取ることができます。
公式ドキュメントには、iOSの場合クリップボードを利用するということは記載されています。
しかし、Firebase SDKの実装を見ると、デバイスの情報なども利用してサーバからダイナミックリンクURLを取得しているように見えます。
実際に次のようにアプリを起動すると、クリップボードにディープリンクURLがコピーされていない場合でも、ディープリンクURLを取得できます。
- アプリをインストールしていないデバイスでディープリンクのURLを開く
- iOSでアプリがインストールされてない場合に表示されるプレビューページのOpenボタンをタップする
テキスト
のようなURL形式ではない文字列をクリップボードにコピーする(OpenボタンをタップしたときにディープリンクURLがクリップボードにコピーされているので上書きする)- アプリをインストールして起動する
クリップボードから取得した場合は間違いなくユーザが意図したディープリンクURLと言えますが、それ以外の方法で取得したURLはユーザとは無関係のURLの可能性があります。
これらを区別するために、iOS向けのDynamic Links SDKには受け取ったURLの信頼性を表すmatchTypeという項目があります。
matchTypeの値がunique
でない場合はユーザが意図しないURLをアプリが受け取っている可能性があります。4
そのため、matchTypeの値がunique
であるか判定してからURLを処理します。このように対応することで別のユーザがデータを受け取りません。
アプリケーションで利用しているReact Native FirebaseではアプリケーションにmatchTypeが渡されないため、ライブラリにパッチを適用する必要があります。
パッチを適用する対象はiOSのみです。React Native Firebaseに含まれるNative Moduleは、FirebaseのSDKからmatchTypeを受け取っているため、JavaScript Moduleに渡す機能を追加する必要があります。
決定
ディープリンクの実現方式として、Dynamic Linksを利用します。
- カスタムURLスキームは自由に設定できるため、作成したURLを別のアプリに乗っ取られるリスクがあります。↩
- AndroidでディープリンクのURLをLikingで読み取れないというissueがあり、適切な回避方法の調査が完了していないためX(対応が難しい)としています。↩
- アプリへの導線はアプリのインストールを促し、インストール後もURLを読み取れる機能です。↩
- iOSで受信する > 6.オプションの警告にあるように、matchTypeの値が
unique
にならないケースがあります。↩