获取我们在 Firebase 峰会上发布的所有信息,了解 Firebase 可如何帮助您加快应用开发速度并满怀信心地运行应用。了解详情

Conquiste novos usuários para seu aplicativo, permitindo que os usuários compartilhem o conteúdo do seu aplicativo

Uma das maneiras mais eficazes de fazer com que novos usuários instalem seu aplicativo é permitir que seus usuários compartilhem conteúdo de seu aplicativo com os amigos. Com Dynamic Links, você pode criar uma ótima experiência de compartilhamento de usuário para usuário: os usuários que recebem recomendações de conteúdo de seus amigos podem clicar em um link e ser direcionados diretamente para o conteúdo compartilhado em seu aplicativo, mesmo que precisem acessar o aplicativo Store ou Google Play Store para instalar seu aplicativo primeiro.

Ao combinar a aderência das referências de usuários e a persistência dos links dinâmicos, você pode criar recursos de referência e compartilhamento de usuário para usuário que atraem novos usuários, atraindo-os diretamente para o conteúdo do seu aplicativo ou veiculando promoções que beneficiam mutuamente o referenciador e o referido. .

Principais benefícios

  • Novos usuários que abrem seu aplicativo pela primeira vez obtêm uma experiência de primeira execução personalizada que é contextualizada com base no que seu amigo deseja compartilhar com eles. Por exemplo, você pode exibir o conteúdo que foi compartilhado com eles ou conectá-los automaticamente ao amigo que os convidou.
  • Torna mais fácil para os usuários compartilhar conteúdo com seus amigos em várias plataformas, independentemente de seus amigos terem seu aplicativo instalado ou não.

Veja como começar!

Configure um novo projeto do Firebase e instale o SDK do Dynamic Links em seu aplicativo.

A instalação do SDK do Dynamic Links permite que o Firebase transmita dados sobre o Dynamic Link para o aplicativo, inclusive após a instalação do aplicativo pelo usuário.

Agora é hora de configurar os links que os usuários podem enviar para seus amigos. Não se preocupe se os amigos de seus usuários ainda não tiverem o aplicativo instalado; Dynamic Links pode cuidar disso para você.

Para cada elemento de conteúdo que você deseja compartilhar, crie um link dinâmico .

Ao criar o link dinâmico, você precisará fornecer um URL HTTP ou HTTPS como o parâmetro de link que será usado para identificar o conteúdo que você está compartilhando. Se você tiver um site com conteúdo equivalente, use os URLs do seu site. Isso garantirá que esses links sejam renderizados corretamente em uma plataforma que não oferece suporte a links dinâmicos, como um navegador de desktop. Por exemplo:

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

Você também pode adicionar informações adicionais à carga de dados adicionando parâmetros codificados por URL, por exemplo, para indicar que o link é destinado a um usuário específico, como em um convite para um jogo.

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

Antes de compartilhar esses links, convém usar a API do encurtador de URL do Firebase Dynamic Links para gerar URLs mais amigáveis. Um link dinâmico curto se parece com o exemplo a seguir:

https://example.page.link/WXYZ

Qualquer que seja o link que você usar, quando os usuários abrirem o Dynamic Link em seus dispositivos, o aplicativo especificado pelo parâmetro apn (no Android) ou os parâmetros ibi e isi (no iOS) levará os usuários à Play Store ou App Store para instalar o aplicativo se ainda não estiver instalado. Então, quando o aplicativo é instalado e aberto, a URL especificada no parâmetro 'link' é passada para o aplicativo.

Primeiro, dê uma olhada neste exemplo simples de um aplicativo de bate-papo baseado em sala, como o Hangouts, que gera links para convidar pessoas para salas de bate-papo.

iOS

chat app screenshotchat app screenshot with share sheet

Android

chat app screenshotchat app screenshot with share sheet

Rápido

Observação: este produto Firebase não está disponível em destinos macOS, Mac Catalyst, tvOS ou 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
}

Objetivo-C

Observação: este produto Firebase não está disponível em destinos macOS, Mac Catalyst, tvOS ou 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
}

Depois de ter um link dinâmico, você pode adicionar um botão de compartilhamento à sua interface do usuário que iniciará o fluxo de compartilhamento de plataforma padrão:

Rápido

Observação: este produto Firebase não está disponível em destinos macOS, Mac Catalyst, tvOS ou 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)
}

Objetivo-C

Observação: este produto Firebase não está disponível em destinos macOS, Mac Catalyst, tvOS ou 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"))
}

Neste exemplo, a interface do usuário de compartilhamento padrão apresenta automaticamente uma lista de aplicativos para compartilhar o link, portanto, é algo que você pode configurar em seu próprio aplicativo com apenas algumas linhas de código.

Em vez de o usuário selecionar contatos e redigir a mensagem em seu aplicativo, essas ações são delegadas ao aplicativo escolhido na caixa de diálogo de compartilhamento. Além disso, delegar o compartilhamento para outros aplicativos significa que você não precisa solicitar ao usuário permissões de contatos e permite que os usuários selecionem em uma lista de contatos expandida no aplicativo escolhido. Para facilitar melhor o compartilhamento social, você pode adicionar metadados de visualização de mídia social ao seu link dinâmico que será exibido junto com o link nos principais canais sociais.

Às vezes, porém, apenas enviar um link simples sem texto não é suficiente para uma referência atraente. Ao acompanhar o link com uma mensagem curta e, se possível, uma apresentação mais rica, os usuários podem entender a proposta de valor da indicação ao recebê-la:

iOS

rewarded referral screenshotrewarded referral screenshot with share sheet

Android

rewarded referral screenshotrewarded referral screenshot with share sheet

Embora isso seja mais complexo do que o último exemplo, a abordagem será mais ou menos a mesma. Nesta tela há um grande gráfico com a proposta de valor do convite e botões para compartilhamento nos principais canais sociais. Há alguma redundância nesse fluxo de interface do usuário — alguns canais de compartilhamento são apresentados individualmente para permitir mais personalização de mensagens específicas do canal, como adicionar uma linha de assunto aos convites por email. Neste menu de convites, nós:

  • Apresente e-mail, mensagem de texto e botões de compartilhamento de link de cópia e personalize suas mensagens adequadamente. O e-mail incluirá um assunto e pode incluir um corpo mais longo com quebras de linha, imagens e espaços em branco; o texto deve incluir um corpo mais curto com quebras de linha, mas pouco espaço em branco e sem imagens; e a cópia de link deve apenas copiar o link e nada mais.
  • Use a interface do usuário de compartilhamento do sistema para todo o resto, incluindo uma pequena mensagem de convite para acompanhar o link.
  • Link direto via esquema de URL ou link universal para outro aplicativo que tenha lógica especial para lidar com os convites do seu aplicativo. Isso não funcionará fora de uma parceria entre sua organização e o outro aplicativo e provavelmente não é uma opção para organizações menores. Dito isso, alguns aplicativos podem documentar publicamente seu comportamento de links universais/deep. Implementaremos uma versão fictícia disso em nosso exemplo.

Primeiro, defina um tipo de conteúdo de convite, que encapsula apenas as informações em um convite e não contém nenhuma funcionalidade. Dessa forma, você pode começar com os tipos de dados e pensar em seu código em termos de como ele reúne esses dados.

Rápido

Observação: este produto Firebase não está disponível em destinos macOS, Mac Catalyst, tvOS ou 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

}

Objetivo-C

Observação: este produto Firebase não está disponível em destinos macOS, Mac Catalyst, tvOS ou 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
)

O único dado necessário aqui é o URL, sem o qual você não pode convidar usuários para seu aplicativo. Os outros dados são claramente estruturados para enviar e-mails, o que os torna um pouco estranhos em alguns outros casos - ao enviar um convite por texto, a sinopse que acompanha o link pode ser semelhante a um assunto de e-mail, mas ao compartilhar em mídias sociais o link que acompanha o texto pode ser mais como um corpo de e-mail. Você terá que experimentar isso sozinho para encontrar o melhor equilíbrio para seu aplicativo e, se não tiver certeza, sempre poderá usar um serviço como o Configuração remota para alterar os valores de texto após a inicialização do aplicativo.

Rápido

Observação: este produto Firebase não está disponível em destinos macOS, Mac Catalyst, tvOS ou 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()

}

Objetivo-C

Observação: este produto Firebase não está disponível em destinos macOS, Mac Catalyst, tvOS ou 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) {
        // ...
    }
}

Agora, tudo o que resta é conectar isso a um componente de interface do usuário de sua escolha. Para a implementação completa desse fluxo de convites, consulte os exemplos no GitHub para iOS e Android .

Esses são todos os métodos para permitir que seus usuários enviem convites para seus amigos, que é a solução de convite mais leve. Muitos aplicativos populares também entregam convites enviando e-mails por meio de seu próprio back-end, o que requer a integração de um serviço de envio de e-mail, mas oferece vários benefícios que não estão disponíveis com apenas algumas pequenas desvantagens.

Prós:

  • Habilita emails com marcação complexa que não pode ser modificada pelo usuário antes do envio.
  • Permite rastreamento/análise mais granular (ou seja, enviar sucessos e falhas em seu back-end).

Contras:

  • E-mails com maior probabilidade de serem sinalizados como spam
  • Requer integração com um serviço de entrega de e-mail
  • Requer permissões de contatos no aplicativo

Geralmente, o envio de convites por meio de seu próprio serviço de entrega de e-mail oferece uma experiência de convite mais consistente e potencialmente mais rica ao custo da versatilidade.

Abra o conteúdo vinculado em seu aplicativo

Por fim, você precisa receber o link que é passado para seu aplicativo para poder exibir o conteúdo vinculado ao destinatário. Isso é fácil usando o SDK do Dynamic Links:

iOS

No iOS, você recebe o Dynamic Link implementando o método application:continueUserActivity:restorationHandler: No manipulador de restauração, você pode obter o Dynamic Link chamando handleUniversalLink:completion: . Se um Dynamic Link foi passado para seu aplicativo, você pode obtê-lo na propriedade url do FIRDynamicLink . Por exemplo:

Objetivo-C

Observação: este produto Firebase não está disponível em destinos macOS, Mac Catalyst, tvOS ou watchOS.
[[FIRDynamicLinks dynamicLinks]
    handleUniversalLink:userActivity.webpageURL
             completion:^(FIRDynamicLink * _Nullable dynamicLink,
                          NSError * _Nullable error) {
      NSString *link = dynamicLink.url;
      BOOL strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong;
      // ...
    }];

Rápido

Observação: este produto Firebase não está disponível em destinos macOS, Mac Catalyst, tvOS ou watchOS.
FIRDynamicLinks.dynamicLinks()?.handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
    let link = dynamicLink.url
    let strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong
    // ...
}

Além disso, você deve chamar dynamicLinkFromCustomSchemeURL: no método application:openURL:options: para receber links dinâmicos passados ​​para seu aplicativo como URLs de esquema personalizado. Por exemplo:

Objetivo-C

Observação: este produto Firebase não está disponível em destinos macOS, Mac Catalyst, tvOS ou watchOS.
FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
if (dynamicLink) {
  NSString *link = dynamicLink.url;
  BOOL strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong;
  // ...
  return YES;
}

Rápido

Observação: este produto Firebase não está disponível em destinos macOS, Mac Catalyst, tvOS ou watchOS.
let dynamicLink = FIRDynamicLinks.dynamicLinks()?.dynamicLinkFromCustomSchemeURL(url)
if let dynamicLink = dynamicLink {
  let link = dynamicLink.url
  let strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong
  // ...
  return true
}

Agora que você tem o valor do parâmetro link , você pode exibir o conteúdo vinculado ao destinatário ou processar os dados especificados pelo parâmetro de alguma outra maneira. Uma biblioteca de roteamento de URL, como JLRoutes , pode ajudar nessa tarefa.

Se você estiver recebendo um link destinado a um destinatário específico, verifique se a confiança de correspondência do link dinâmico é strong antes de executar qualquer lógica específica do usuário.

Android

No Android, você usa o método getDynamicLink() para obter dados do Dynamic Link:

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

Agora que você tem o valor do parâmetro link , você pode exibir o conteúdo vinculado ao destinatário ou processar os dados especificados pelo parâmetro de alguma outra maneira. Uma biblioteca de roteamento de URL pode ajudar nessa tarefa.