Firebase Summit で発表されたすべての情報をご覧ください。Firebase を使用してアプリ開発を加速し、自信を持ってアプリを実行する方法を紹介しています。詳細

ユーザーがアプリのコンテンツを共有できるようにして、アプリの新規ユーザーを獲得します

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

新規ユーザーにアプリをインストールしてもらう最も効果的な方法の 1 つは、ユーザーがアプリのコンテンツを友達と共有できるようにすることです。 Dynamic Links を使用すると、ユーザー間の優れた共有エクスペリエンスを作成できます。友人からコンテンツのおすすめを受け取ったユーザーは、リンクをクリックして、アプリにアクセスしなければならない場合でも、アプリ内の共有コンテンツに直接移動できます。ストアまたは Google Play ストアにアクセスして、最初にアプリをインストールします。

ユーザー紹介の持続性と Dynamic Links の持続性を組み合わせることで、ユーザー間の共有機能と紹介機能を作成して、新しいユーザーをアプリのコンテンツに直接誘導したり、紹介者と被紹介者に相互に利益をもたらすプロモーションを提供したりすることで、新しいユーザーを呼び込むことができます。 .

主な利点

  • アプリを初めて開いた新規ユーザーは、友人が共有したい内容に基づいてコンテキスト化された、カスタマイズされた初回実行エクスペリエンスを取得します。たとえば、共有されたコンテンツを表示したり、招待した友達と自動的に接続したりできます。
  • 友達があなたのアプリをインストールしているかどうかに関係なく、ユーザーがプラットフォーム間で友達と簡単にコンテンツを共有できるようにします。

始める方法は次のとおりです。

新しい Firebase プロジェクトを設定し、Dynamic Links SDK をアプリにインストールします。

Dynamic Links SDK をインストールすると、ユーザーがアプリをインストールした後など、Firebase は Dynamic Link に関するデータをアプリに渡すことができます。

次に、ユーザーが友人に送信できるリンクを設定します。ユーザーの友達がまだアプリをインストールしていなくても心配はいりません。 Dynamic Links がそれを処理します。

共有可能にしたいコンテンツの要素ごとに、ダイナミック リンクを作成します

ダイナミック リンクを作成するときは、共有しているコンテンツを識別するために使用されるlinkパラメーターとして HTTP または HTTPS URL を指定する必要があります。同等のコンテンツを含む Web サイトがある場合は、Web サイトの URL を使用する必要があります。これにより、これらのリンクは、デスクトップ ブラウザーなど、Dynamic Links をサポートしていないプラットフォームで正しくレンダリングされます。例:

https://example.page.link/?link=https://www.example.com/content?item%3D1234&apn=com.example.android&ibi=com.example.ios&isi=12345

URL エンコードされたパラメーターを追加することで、データ ペイロードに追加情報を追加することもできます。たとえば、ゲームへの招待など、特定のユーザー向けのリンクであることを示すことができます。

https://example.page.link/?link=https://www.example.com/invitation?gameid%3D1234%26referrer%3D555&apn=com.example.android&ibi=com.example.ios&isi=12345

これらのリンクを共有する前に、 Firebase Dynamic Links URL Shorter APIを使用して、見やすい URL を生成することをお勧めします。短いダイナミック リンクは次の例のようになります:

https://example.page.link/WXYZ

どちらのリンクを使用しても、ユーザーがデバイスでダイナミック リンクを開くと、 apnパラメーター (Android の場合) またはibiおよびisiパラメーター (iOS の場合) で指定されたアプリは、ユーザーを Play ストアまたは App Store に誘導してアプリをインストールします。まだインストールされていない場合。次に、アプリをインストールして開くと、'link' パラメーターで指定された URL がアプリに渡されます。

まず、チャット ルームに人々を招待するためのリンクを生成する、ハングアウトのようなルーム ベースのチャット アプリの簡単な例を見てみましょう。

iOS

chat app screenshotchat app screenshot with share sheet

アンドロイド

chat app screenshotchat app screenshot with share sheet

迅速

注:この Firebase 製品は、macOS、Mac Catalyst、tvOS、または watchOS ターゲットでは使用できません。
func generateContentLink() -> URL {
  let baseURL = URL(string: "https://your-custom-name.page.link")!
  let domain = "https://your-app.page.link"
  let linkBuilder = DynamicLinkComponents(link: baseURL, domainURIPrefix: domain)
  linkBuilder?.iOSParameters = DynamicLinkIOSParameters(bundleID: "com.your.bundleID")
  linkBuilder?.androidParameters =
      DynamicLinkAndroidParameters(packageName: "com.your.packageName")


  // Fall back to the base url if we can't generate a dynamic link.
  return linkBuilder?.link ?? baseURL
}

Objective-C

注:この Firebase 製品は、macOS、Mac Catalyst、tvOS、または watchOS ターゲットでは使用できません。
- (NSURL *)generateContentLink {
  NSURL *baseURL = [NSURL URLWithString:@"https://your-custom-name.page.link"];
  NSString *domain = @"https://your-app.page.link";
  FIRDynamicLinkComponents *builder = [[FIRDynamicLinkComponents alloc] initWithLink:baseURL domainURIPrefix:domain];
  builder.iOSParameters = [FIRDynamicLinkIOSParameters parametersWithBundleID:@"com.your.bundleID"];
  builder.androidParameters = [FIRDynamicLinkAndroidParameters parametersWithPackageName:@"com.your.packageName"];

  // Fall back to the base url if we can't generate a dynamic link.
  return builder.link ?: baseURL;
}

Java

public static Uri generateContentLink() {
    Uri baseUrl = Uri.parse("https://your-custom-name.page.link");
    String domain = "https://your-app.page.link";

    DynamicLink link = FirebaseDynamicLinks.getInstance()
            .createDynamicLink()
            .setLink(baseUrl)
            .setDomainUriPrefix(domain)
            .setIosParameters(new DynamicLink.IosParameters.Builder("com.your.bundleid").build())
            .setAndroidParameters(new DynamicLink.AndroidParameters.Builder("com.your.packageName").build())
            .buildDynamicLink();

    return link.getUri();
}

Kotlin+KTX

fun generateContentLink(): Uri {
    val baseUrl = Uri.parse("https://your-custom-name.page.link")
    val domain = "https://your-app.page.link"

    val link = FirebaseDynamicLinks.getInstance()
            .createDynamicLink()
            .setLink(baseUrl)
            .setDomainUriPrefix(domain)
            .setIosParameters(DynamicLink.IosParameters.Builder("com.your.bundleid").build())
            .setAndroidParameters(DynamicLink.AndroidParameters.Builder("com.your.packageName").build())
            .buildDynamicLink()

    return link.uri
}

動的リンクを作成したら、標準のプラットフォーム共有フローを起動する共有ボタンを UI に追加できます。

迅速

注:この Firebase 製品は、macOS、Mac Catalyst、tvOS、または watchOS ターゲットでは使用できません。
lazy private var shareController: UIActivityViewController = {
  let activities: [Any] = [
    "Learn how to share content via Firebase",
    URL(string: "https://firebase.google.com")!
  ]
  let controller = UIActivityViewController(activityItems: activities,
                                            applicationActivities: nil)
  return controller
}()

@IBAction func shareButtonPressed(_ sender: Any) {
  let inviteController = UIStoryboard(name: "Main", bundle: nil)
    .instantiateViewController(withIdentifier: "InviteViewController")
  self.navigationController?.pushViewController(inviteController, animated: true)
}

Objective-C

注:この Firebase 製品は、macOS、Mac Catalyst、tvOS、または watchOS ターゲットでは使用できません。
- (UIActivityViewController *)shareController {
  if (_shareController == nil) {
    NSArray *activities = @[
      @"Learn how to share content via Firebase",
      [NSURL URLWithString:@"https://firebase.google.com"]
    ];
    UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:activities applicationActivities:nil];
    _shareController = controller;
  }
  return _shareController;
}

- (IBAction)shareLinkButtonPressed:(UIView *)sender {
  if (![sender isKindOfClass:[UIView class]]) {
    return;
  }

  self.shareController.popoverPresentationController.sourceView = sender;
  [self presentViewController:self.shareController animated:YES completion:nil];
}

Java

private void onShareClicked() {
    Uri link = DynamicLinksUtil.generateContentLink();

    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_TEXT, link.toString());

    startActivity(Intent.createChooser(intent, "Share Link"));
}

Kotlin+KTX

private fun onShareClicked() {
    val link = DynamicLinksUtil.generateContentLink()

    val intent = Intent(Intent.ACTION_SEND)
    intent.type = "text/plain"
    intent.putExtra(Intent.EXTRA_TEXT, link.toString())

    startActivity(Intent.createChooser(intent, "Share Link"))
}

この例では、デフォルトの共有 UI がリンクを共有するためのアプリのリストを自動的に表示するため、数行のコードで独自のアプリに設定できます。

ユーザーが連絡先を選択してアプリでメッセージを作成するのではなく、これらのアクションは、共有ダイアログから選択したアプリに委任されます。さらに、共有を他のアプリに委任すると、ユーザーに連絡先のアクセス許可を求める必要がなくなり、ユーザーは選択したアプリ内の拡張された連絡先リストから選択できるようになります。ソーシャル共有をより容易にするために、ソーシャル メディア プレビュー メタデータをダイナミック リンクに追加できます。このメタデータは、主要なソーシャル チャネルのリンクと共に表示されます。

ただし、テキストのない裸のリンクを送信するだけでは、説得力のある紹介には不十分な場合があります。リンクに短いメッセージを付け、可能であればより充実したプレゼンテーションを付けることで、ユーザーは紹介を受けたときにその価値提案を理解できます。

iOS

rewarded referral screenshotrewarded referral screenshot with share sheet

アンドロイド

rewarded referral screenshotrewarded referral screenshot with share sheet

これは前の例よりも複雑ですが、アプローチはほぼ同じです。この画面には、招待の価値提案と、主要なソーシャル チャネルに共有するためのボタンを含む大きなグラフィックがあります。この UI フローには冗長性があります。一部の共有チャネルは個別に表示され、電子メールの招待に件名を追加するなど、チャネル固有のメッセージのカスタマイズを可能にします。この招待メニューでは、次のことを行います。

  • メール、テキスト メッセージ、コピー リンクの共有ボタンを表示し、それらのメッセージを適切にカスタマイズします。電子メールには件名が含まれ、改行、画像、および空白を含む長い本文を含めることができます。テキストには、改行を含む短い本文を含める必要がありますが、空白はほとんどなく、画像は含めないでください。リンクのコピーは、リンクをコピーするだけで、他には何もコピーしません。
  • リンクに付随する短い招待メッセージなど、その他すべてにシステム共有 UI を使用します。
  • アプリの招待を処理するための特別なロジックを持つ別のアプリへの URL スキームまたはユニバーサル リンクを介したディープ リンク。これは、組織と他のアプリとの間のパートナーシップの外では機能せず、小規模な組織の場合は選択肢にならない可能性があります。とはいえ、一部のアプリは、ユニバーサル/ディープリンクの動作を公開している場合があります。サンプルでは、​​これのダミー バージョンを実装します。

最初に、招待の情報のみをカプセル化し、機能を含まない招待コンテンツ タイプを定義します。このようにして、データ型から始めて、そのデータをどのように組み合わせるかという観点からコードを考えることができます。

迅速

注:この Firebase 製品は、macOS、Mac Catalyst、tvOS、または watchOS ターゲットでは使用できません。
/// The content within an invite, with optional fields to accommodate all presenters.
/// This type could be modified to also include an image, for sending invites over email.
struct InviteContent {

  /// The subject of the message. Not used for invites without subjects, like text message invites.
  var subject: String?

  /// The body of the message. Indispensable content should go here.
  var body: String?

  /// The URL containing the invite. In link-copy cases, only this field will be used.
  var link: URL

}

Objective-C

注:この Firebase 製品は、macOS、Mac Catalyst、tvOS、または watchOS ターゲットでは使用できません。
/// The content within an invite, with optional fields to accommodate all presenters.
/// This type could be modified to also include an image, for sending invites over email.
@interface InviteContent : NSObject <NSCopying>

/// The subject of the message. Not used for invites without subjects, like text message invites.
@property (nonatomic, readonly, nullable) NSString *subject;

/// The body of the message. Indispensable content should go here.
@property (nonatomic, readonly, nullable) NSString *body;

/// The URL containing the invite. In link-copy cases, only this field will be used.
@property (nonatomic, readonly) NSURL *link;

- (instancetype)initWithSubject:(nullable NSString *)subject
                           body:(nullable NSString *)body
                           link:(NSURL *)link NS_DESIGNATED_INITIALIZER;

- (instancetype)init NS_UNAVAILABLE;

@end

Java

/**
 * The content of an invitation, with optional fields to accommodate all presenters.
 * This type could be modified to also include an image, for sending invites over email.
 */
public class InviteContent {

    /**
     * The subject of the message. Not used for invites without subjects, like SMS.
     **/
    @Nullable
    public final String subject;

    /**
     * The body of the message. Indispensable content should go here.
     **/
    @Nullable
    public final String body;

    /**
     * The URL containing the link to invite. In link-copy cases, only this field will be used.
     **/
    @NonNull
    public final Uri link;

    public InviteContent(@Nullable String subject, @Nullable String body, @NonNull Uri link) {
        // ...
    }

}

Kotlin+KTX

/**
 * The content of an invitation, with optional fields to accommodate all presenters.
 * This type could be modified to also include an image, for sending invites over email.
 */
data class InviteContent(
    /** The subject of the message. Not used for invites without subjects, like SMS.  */
    val subject: String?,
    /** The body of the message. Indispensable content should go here.  */
    val body: String?,
    /** The URL containing the link to invite. In link-copy cases, only this field will be used.  */
    val link: Uri
)

ここで必要なデータは URL だけです。これがないと、ユーザーをアプリに招待することはできません。他のデータは、電子メールを送信するために明確に構造化されているため、他の場合には少し厄介です.テキストで招待状を送信する場合、リンクに付随する宣伝文句は電子メールの件名と同じように読めるかもしれませんが、ソーシャルメディアに共有する場合.テキストに付随するリンクは、電子メールの本文に似ている場合があります。アプリの最適なバランスを見つけるには、これを自分で試す必要があります。不明な場合は、いつでもRemote Configなどのサービスを使用して、アプリの起動後にテキスト値を変更できるようにすることができます。

迅速

注:この Firebase 製品は、macOS、Mac Catalyst、tvOS、または watchOS ターゲットでは使用できません。
/// A type responsible for presenting an invite given using a specific method
/// given the content of the invite.
protocol InvitePresenter {

  /// The name of the presenter. User-visible.
  var name: String { get }

  /// An icon representing the invite method. User-visible.
  var icon: UIImage? { get }

  /// Whether or not the presenter's method is available. iOS devices that aren't phones
  /// may not be able to send texts, for example.
  var isAvailable: Bool { get }

  /// The content of the invite. Some of the content type's fields may be unused.
  var content: InviteContent { get }

  /// Designated initializer.
  init(content: InviteContent, presentingController: UIViewController)

  /// This method should cause the presenter to present the invite and then handle any actions
  /// required to complete the invite flow.
  func sendInvite()

}

Objective-C

注:この Firebase 製品は、macOS、Mac Catalyst、tvOS、または watchOS ターゲットでは使用できません。
/// A type responsible for presenting an invite given using a specific method
/// given the content of the invite.
@protocol InvitePresenter <NSObject>

/// The name of the presenter. User-visible.
@property (nonatomic, readonly) NSString *name;

/// An icon representing the invite method. User-visible.
@property (nonatomic, readonly, nullable) UIImage *icon;

/// Whether or not the presenter's method is available. iOS devices that aren't phones
/// may not be able to send texts, for example.
@property (nonatomic, readonly) BOOL isAvailable;

/// The content of the invite. Some of the content type's fields may be unused.
@property (nonatomic, readonly) InviteContent *content;

/// Designated initializer.
- (instancetype)initWithContent:(InviteContent *)content presentingViewController:(UIViewController *)controller;

/// This method should cause the presenter to present the invite and then handle any actions
/// required to complete the invite flow.
- (void)sendInvite;

@end

Java

/**
 * Presents the invite using a specific method, such as email or social.
 */
public class InvitePresenter {

    /**
     * The user-visible name of the invite method, like 'Email' or 'SMS'
     **/
    public final String name;

    /**
     * An icon representing the invite method.
     **/
    @DrawableRes
    public final int icon;

    /**
     * Whether or not the method is available on this device. For example, SMS is phone only.
     **/
    public final boolean isAvailable;

    /**
     * The Content of the invitation
     **/
    public final InviteContent content;

    public InvitePresenter(String name, @DrawableRes int icon, boolean isAvailable, InviteContent content) {
        // ...
    }

    /**
     * Send the invitation using the specified method.
     */
    public void sendInvite(Context context) {
        // ...
    }

}

Kotlin+KTX

/**
 * Presents the invite using a specific method, such as email or social.
 */
open class InvitePresenter(
    /** The user-visible name of the invite method, like 'Email' or 'SMS'  */
    val name: String,
    /** An icon representing the invite method.  */
    @param:DrawableRes @field:DrawableRes
    val icon: Int,
    /** Whether or not the method is available on this device. For example, SMS is phone only.  */
    val isAvailable: Boolean,
    /** The Content of the invitation  */
    val content: InviteContent
) {
    /**
     * Send the invitation using the specified method.
     */
    open fun sendInvite(context: Context) {
        // ...
    }
}

あとは、これを選択した UI コンポーネントにプラグインするだけです。この招待フローの完全な実装については、iOSおよびAndroid 用の GitHub のサンプルを参照してください。

これらはすべて、ユーザーが友人に招待状を送信できるようにするための方法であり、最も軽量な招待状ソリューションです。多くの人気のあるアプリは、独自のバックエンドを介して電子メールを送信することによっても招待状を配信します。これには、メール送信サービスを統合する必要がありますが、他の方法では利用できない多くの利点があり、いくつかの小さな欠点があるだけです.

長所:

  • ユーザーが送信前に変更できない複雑なマークアップを含む電子メールを有効にします。
  • より詳細な追跡/分析を有効にします (つまり、バックエンドで成功と失敗を送信します)。

短所:

  • スパムとしてフラグが立てられる可能性が高いメール
  • メール配信サービスとの統合が必要
  • アプリ内の連絡先権限が必要です

一般に、独自の電子メール配信サービスを介して招待状を送信すると、汎用性は犠牲になりますが、より一貫性のある、より充実した招待体験が得られます。

アプリでリンクされたコンテンツを開く

最後に、リンクされたコンテンツを受信者に表示できるように、アプリに渡されたリンクを受け取る必要があります。これは、Dynamic Links SDK を使用すると簡単です。

iOS

iOS では、 application:continueUserActivity:restorationHandler:メソッドを実装してダイナミック リンクを受け取ります。復元ハンドラーでは、 handleUniversalLink:completion:を呼び出すことでダイナミック リンクを取得できます。ダイナミック リンクがアプリに渡された場合、 FIRDynamicLinkurlプロパティから取得できます。例えば:

Objective-C

注:この Firebase 製品は、macOS、Mac Catalyst、tvOS、または watchOS ターゲットでは使用できません。
[[FIRDynamicLinks dynamicLinks]
    handleUniversalLink:userActivity.webpageURL
             completion:^(FIRDynamicLink * _Nullable dynamicLink,
                          NSError * _Nullable error) {
      NSString *link = dynamicLink.url;
      BOOL strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong;
      // ...
    }];

迅速

注:この Firebase 製品は、macOS、Mac Catalyst、tvOS、または watchOS ターゲットでは使用できません。
FIRDynamicLinks.dynamicLinks()?.handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
    let link = dynamicLink.url
    let strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong
    // ...
}

さらに、 application:openURL:options:メソッドでdynamicLinkFromCustomSchemeURL:を呼び出して、カスタム スキーム URL としてアプリに渡されるダイナミック リンクを受け取る必要があります。例えば:

Objective-C

注:この Firebase 製品は、macOS、Mac Catalyst、tvOS、または watchOS ターゲットでは使用できません。
FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
if (dynamicLink) {
  NSString *link = dynamicLink.url;
  BOOL strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong;
  // ...
  return YES;
}

迅速

注:この Firebase 製品は、macOS、Mac Catalyst、tvOS、または watchOS ターゲットでは使用できません。
let dynamicLink = FIRDynamicLinks.dynamicLinks()?.dynamicLinkFromCustomSchemeURL(url)
if let dynamicLink = dynamicLink {
  let link = dynamicLink.url
  let strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong
  // ...
  return true
}

linkパラメーターの値を取得したので、リンクされたコンテンツを受信者に表示したり、パラメーターで指定されたデータを別の方法で処理したりできます。 JLRoutesなどの URL ルーティング ライブラリは、このタスクに役立ちます。

特定の受信者向けのリンクを受信して​​いる場合は、ユーザー固有のロジックを実行する前に、ダイナミック リンクの一致の信頼性がstrongことを確認してください。

アンドロイド

Android では、 getDynamicLink()メソッドを使用してダイナミック リンクからデータを取得します。

Java

FirebaseDynamicLinks.getInstance()
        .getDynamicLink(getIntent())
        .addOnCompleteListener(new OnCompleteListener<PendingDynamicLinkData>() {
            @Override
            public void onComplete(@NonNull Task<PendingDynamicLinkData> task) {
                if (!task.isSuccessful()) {
                    // Handle error
                    // ...
                }

                FirebaseAppInvite invite = FirebaseAppInvite.getInvitation(task.getResult());
                if (invite != null) {
                    // Handle invite
                    // ...
                }
            }
        });

Kotlin+KTX

Firebase.dynamicLinks
        .getDynamicLink(intent)
        .addOnCompleteListener { task ->
            if (!task.isSuccessful) {
                // Handle error
                // ...
            }

            val invite = FirebaseAppInvite.getInvitation(task.result)
            if (invite != null) {
                // Handle invite
                // ...
            }
        }

linkパラメーターの値を取得したので、リンクされたコンテンツを受信者に表示したり、パラメーターで指定されたデータを別の方法で処理したりできます。 URL ルーティング ライブラリは、このタスクに役立ちます。