Mendapatkan pengguna baru untuk aplikasi dengan memungkinkan pengguna membagikan konten aplikasi Anda

Salah satu cara paling efektif untuk mendorong pengguna baru menginstal aplikasi Anda adalah dengan memungkinkan pengguna membagikan konten aplikasi Anda kepada teman-temannya. Dengan Dynamic Links, Anda dapat menciptakan pengalaman berbagi antarpengguna yang menyenangkan: pengguna yang menerima rekomendasi konten dari temannya dapat mengklik link dan langsung diarahkan ke konten yang dibagikan di aplikasi Anda, meskipun mereka harus membuka App Store atau Google Play Store untuk menginstal aplikasi Anda terlebih dahulu.

Dengan memadukan daya pikat rujukan pengguna dan persistensi Dynamic Links, Anda dapat membuat fitur rujukan dan berbagi antarpengguna yang akan mendatangkan pengguna baru dengan menarik mereka langsung ke konten aplikasi Anda, atau menayangkan promosi yang menguntungkan baik bagi perujuk maupun penerima rujukan.

Manfaat utama

  • Pengguna baru yang membuka aplikasi Anda untuk pertama kalinya mendapatkan pengalaman pertama yang disesuaikan berdasarkan konten yang dibagikan oleh teman mereka. Misalnya, Anda dapat menampilkan konten yang dibagikan dengan mereka, atau menghubungkan mereka secara otomatis dengan teman yang mengundangnya.
  • Memudahkan pengguna untuk membagikan konten kepada teman di berbagai platform, baik teman yang sudah menginstal aplikasi Anda maupun yang belum.

Berikut cara memulainya.

Siapkan project Firebase baru dan instal Dynamic Links SDK ke dalam aplikasi Anda.

Dengan menginstal Dynamic Links SDK, Firebase dapat meneruskan data tentang Dynamic Link ke aplikasi, termasuk setelah pengguna menginstal aplikasi.

Sekarang saatnya menyiapkan link yang dapat dikirimkan pengguna kepada temannya. Jangan khawatir, jika teman pengguna tersebut belum menginstal aplikasi Anda, Dynamic Links bisa mengurusnya untuk Anda.

Buat Dynamic Link untuk setiap elemen konten yang ingin bisa dibagikan.

Ketika membuat Dynamic Link, Anda harus memberikan URL HTTP atau HTTPS sebagai parameter link yang akan digunakan untuk mengidentifikasi konten yang Anda bagikan. Jika Anda memiliki situs dengan konten yang sama, sebaiknya gunakan URL situs Anda. Cara ini akan memastikan bahwa link akan ditampilkan dengan benar di platform yang tidak mendukung Dynamic Links, seperti browser desktop. Contoh:

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

Anda juga dapat memberikan info tambahan ke payload data dengan menambahkan parameter berenkode URL—misalnya, untuk menunjukkan bahwa link tersebut ditujukan bagi pengguna tertentu, seperti pada undangan game.

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

Sebelum membagikan link ini, sebaiknya gunakan API penyingkat URL Firebase Dynamic Links untuk menghasilkan URL yang lebih mudah digunakan. Dynamic Link pendek terlihat seperti contoh berikut:

https://example.page.link/WXYZ

Link mana pun yang Anda gunakan, saat pengguna membuka Dynamic Link di perangkatnya, jika aplikasi yang ditetapkan oleh parameter apn (di Android) atau parameter ibi dan isi (di iOS) belum diinstal, pengguna akan diarahkan ke Play Store atau App Store untuk menginstalnya. Kemudian, setelah aplikasi diinstal dan dibuka, URL yang ditetapkan dalam parameter 'link' akan diteruskan ke aplikasi tersebut.

Pertama, lihat contoh sederhana aplikasi chat berbasis ruang yang mirip Hangouts ini, yang menghasilkan link untuk mengundang pengguna masuk ke ruang chat.

iOS

screenshot aplikasi chat Screenshot aplikasi chat dengan lembar berbagi

Android

screenshot aplikasi chat Screenshot aplikasi chat dengan lembar berbagi

Swift

Catatan: Produk Firebase ini tidak tersedia di target macOS, Mac Catalyst, tvOS, atau 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

Catatan: Produk Firebase ini tidak tersedia di target macOS, Mac Catalyst, tvOS, atau 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;
}

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
}

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();
}

Setelah memiliki link dinamis, Anda dapat menambahkan tombol berbagi ke UI Anda. Tombol ini akan meluncurkan alur berbagi platform standar:

Swift

Catatan: Produk Firebase ini tidak tersedia di target macOS, Mac Catalyst, tvOS, atau 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

Catatan: Produk Firebase ini tidak tersedia di target macOS, Mac Catalyst, tvOS, atau 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];
}

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"))
}

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"));
}

Dalam contoh ini, UI berbagi default secara otomatis menyajikan daftar aplikasi untuk membagikan link, jadi Anda dapat mengatur hal tersebut di aplikasi Anda sendiri hanya dengan beberapa baris kode.

Pengguna tidak perlu memilih kontak dan menulis pesan di aplikasi Anda karena tindakan ini didelegasikan ke aplikasi yang mereka pilih dari dialog bagikan. Selain itu, dengan mendelegasikan tindakan berbagi ke aplikasi lain, Anda tidak perlu meminta izin kontak kepada pengguna dan pengguna dapat memilih dari daftar kontak yang lebih luas dalam aplikasi yang ia pilih. Untuk memfasilitasi tindakan berbagi ke media sosial dengan lebih baik, Anda dapat menambahkan metadata pratinjau media sosial ke link dinamis yang akan ditampilkan bersama dengan link di saluran sosial utama.

Namun terkadang, mengirim link saja tanpa teks tidak cukup untuk membuat rujukan yang menarik. Dengan menyertakan pesan singkat pada link, dan penyajian yang lebih lengkap jika memungkinkan, pengguna dapat memahami proposisi nilai rujukan ketika menerimanya:

iOS

screenshot rujukan berinsentif screenshot rujukan berinsentif dengan lembar berbagi

Android

screenshot rujukan berinsentif screenshot rujukan berinsentif dengan lembar berbagi

Meskipun ini lebih kompleks daripada contoh sebelumnya, pendekatannya kurang lebih sama. Di layar ini ada sebuah gambar besar dengan proposisi nilai undangan dan tombol untuk berbagi ke saluran sosial utama. Ada beberapa redundansi dalam alur UI ini. Beberapa saluran berbagi disajikan secara terpisah untuk memungkinkan penyesuaian pesan yang lebih spesifik bagi saluran tersebut, seperti menambahkan baris subjek pada undangan email. Dalam menu undangan ini, kita:

  • Menyajikan tombol berbagi melalui email, pesan teks, dan salin link, serta menyesuaikan pesannya. Email akan menyertakan subjek dan dapat menyertakan teks isi yang lebih panjang dengan jeda baris, gambar, dan spasi kosong; pesan teks akan menyertakan isi yang lebih singkat dengan jeda baris, tetapi dengan spasi kosong yang lebih kecil dan tanpa gambar; dan penyalinan link hanya akan menyalin link tanpa elemen lainnya.
  • Menggunakan UI berbagi sistem untuk yang lainnya, termasuk pesan undangan singkat untuk menyertai link.
  • Menggunakan deep link melalui skema URL atau link universal ke aplikasi lain yang memiliki logika khusus untuk menangani undangan aplikasi Anda. Fitur ini tidak dapat digunakan jika tidak ada kerja sama antara organisasi Anda dan aplikasi lain tersebut, dan mungkin tidak sesuai untuk organisasi yang lebih kecil. Namun demikian, mungkin ada sejumlah aplikasi yang mendokumentasikan perilaku universal/deep linking-nya secara publik. Kita akan menerapkan versi dummy terkait hal ini dalam contoh kita.

Pertama, tentukan jenis konten undangan, yang hanya mencakup informasi dalam undangan tanpa fungsionalitas apa pun. Dengan cara ini, Anda dapat mulai dari jenis data dan memikirkan bagaimana kode Anda dapat menyatukan data tersebut.

Swift

Catatan: Produk Firebase ini tidak tersedia di target macOS, Mac Catalyst, tvOS, atau 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

Catatan: Produk Firebase ini tidak tersedia di target macOS, Mac Catalyst, tvOS, atau 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

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
)

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) {
        // ...
    }

}

Satu-satunya data yang diperlukan di sini adalah URL, karena tanpanya Anda tidak dapat mengundang pengguna ke aplikasi Anda. Bagian data lainnya terstruktur secara jelas untuk mengirim email, sehingga kurang sesuai untuk penggunaan lain. Misalnya, saat mengirim undangan melalui pesan teks, uraian yang menyertai link mungkin akan tampak seperti subjek email, tetapi saat dibagikan ke media sosial, link yang menyertai teks mungkin akan lebih mirip isi email. Anda harus bereksperimen sendiri dengan hal ini untuk menemukan penggunaan terbaik bagi aplikasi Anda. Jika merasa tidak yakin, Anda dapat menggunakan layanan seperti Remote Config yang bisa digunakan untuk mengubah nilai teks setelah peluncuran aplikasi.

Swift

Catatan: Produk Firebase ini tidak tersedia di target macOS, Mac Catalyst, tvOS, atau 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

Catatan: Produk Firebase ini tidak tersedia di target macOS, Mac Catalyst, tvOS, atau 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

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) {
        // ...
    }
}

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) {
        // ...
    }

}

Sekarang Anda hanya tinggal menggabungkannya ke komponen UI yang Anda pilih. Untuk mengetahui implementasi lengkap dari alur undangan ini, lihat contoh di GitHub untuk iOS dan Android.

Semua ini adalah metode untuk membuat pengguna dapat mengirim undangan kepada teman-teman mereka, yang merupakan solusi undangan paling mudah. Banyak aplikasi populer juga mengirimkan undangan dengan mengirim email melalui backend-nya sendiri. Metode ini memerlukan integrasi layanan pengiriman email, tetapi menawarkan sejumlah manfaat yang tidak tersedia jika menggunakan cara lain, dengan hanya beberapa kelemahan kecil.

Kelebihan:

  • Memungkinkan penggunaan email dengan markup kompleks yang tidak dapat dimodifikasi oleh pengguna sebelum pengiriman.
  • Memungkinkan pelacakan/analisis yang lebih terperinci (misalnya keberhasilan dan kegagalan pengiriman di backend Anda).

Kekurangan:

  • Memperbesar kemungkinan email akan ditandai sebagai spam
  • Memerlukan integrasi dengan layanan pengiriman email
  • Memerlukan izin kontak dalam aplikasi

Secara umum, mengirim undangan melalui layanan pengiriman email Anda sendiri akan meningkatkan konsistensi dan kualitas pengiriman undangan, meskipun harus mengorbankan fleksibilitas.

Membuka konten yang tertaut di aplikasi

Terakhir, Anda harus menerima link yang diteruskan ke aplikasi Anda agar dapat menampilkan konten yang ditautkan kepada penerima. Proses ini mudah dilakukan dengan Dynamic Links SDK:

iOS

Di iOS, Anda menerima Dynamic Link dengan menerapkan metode application:continueUserActivity:restorationHandler:. Di pengendali pemulihan, Anda bisa mendapatkan Dynamic Link dengan memanggil handleUniversalLink:completion:. Jika Dynamic Link diteruskan ke aplikasi, Anda bisa mendapatkannya dari properti url pada FIRDynamicLink. Contoh:

Objective-C

Catatan: Produk Firebase ini tidak tersedia di target macOS, Mac Catalyst, tvOS, atau watchOS.
[[FIRDynamicLinks dynamicLinks]
    handleUniversalLink:userActivity.webpageURL
             completion:^(FIRDynamicLink * _Nullable dynamicLink,
                          NSError * _Nullable error) {
      NSString *link = dynamicLink.url;
      BOOL strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong;
      // ...
    }];

Swift

Catatan: Produk Firebase ini tidak tersedia di target macOS, Mac Catalyst, tvOS, atau watchOS.
FIRDynamicLinks.dynamicLinks()?.handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
    let link = dynamicLink.url
    let strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong
    // ...
}

Selain itu, Anda harus memanggil dynamicLinkFromCustomSchemeURL: dalam metode application:openURL:options: untuk menerima Dynamic Link yang diteruskan ke aplikasi Anda sebagai URL skema kustom. Misalnya:

Objective-C

Catatan: Produk Firebase ini tidak tersedia di target macOS, Mac Catalyst, tvOS, atau watchOS.
FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
if (dynamicLink) {
  NSString *link = dynamicLink.url;
  BOOL strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong;
  // ...
  return YES;
}

Swift

Catatan: Produk Firebase ini tidak tersedia di target macOS, Mac Catalyst, tvOS, atau watchOS.
let dynamicLink = FIRDynamicLinks.dynamicLinks()?.dynamicLinkFromCustomSchemeURL(url)
if let dynamicLink = dynamicLink {
  let link = dynamicLink.url
  let strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong
  // ...
  return true
}

Setelah mendapatkan nilai untuk parameter link, kini Anda dapat menampilkan konten yang ditautkan kepada penerima, atau memproses data yang ditentukan oleh parameter dengan cara lain. Library perutean URL seperti JLRoutes dapat digunakan untuk tugas ini.

Jika Anda menerima link yang ditujukan untuk penerima tertentu, pastikan tingkat kecocokan Dynamic Link adalah strong sebelum menjalankan logika khusus pengguna.

Android

Di Android, Anda harus menggunakan metode getDynamicLink() untuk mendapatkan data dari Dynamic Link:

Kotlin+KTX

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

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

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
                    // ...
                }
            }
        });

Setelah mendapatkan nilai untuk parameter link, kini Anda dapat menampilkan konten yang ditautkan kepada penerima, atau memproses data yang ditentukan oleh parameter dengan cara lain. Library perutean URL dapat berguna untuk tugas ini.