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

Obtenga nuevos usuarios para su aplicación al permitir que los usuarios compartan el contenido de su aplicación

Una de las formas más efectivas de hacer que los nuevos usuarios instalen su aplicación es permitir que sus usuarios compartan contenido de su aplicación con sus amigos. Con Dynamic Links, puede crear una gran experiencia de intercambio de usuario a usuario: los usuarios que reciben recomendaciones de contenido de sus amigos pueden hacer clic en un enlace y acceder directamente al contenido compartido en su aplicación, incluso si tienen que ir a la aplicación. Store o Google Play Store para instalar su aplicación primero.

Al combinar la adherencia de las referencias de los usuarios y la persistencia de Dynamic Links, puede crear funciones de referencia y uso compartido de usuario a usuario que atraigan a nuevos usuarios atrayéndolos directamente al contenido de su aplicación o publicando promociones que beneficien mutuamente al remitente y al referido. .

Beneficios clave

  • Los nuevos usuarios que abren su aplicación por primera vez obtienen una experiencia de primera ejecución personalizada que se contextualiza en función de lo que su amigo quería compartir con ellos. Por ejemplo, puede mostrar el contenido que se compartió con ellos o conectarlos automáticamente con el amigo que los invitó.
  • Hace que sea fácil para los usuarios compartir contenido con sus amigos a través de plataformas, ya sea que sus amigos tengan su aplicación instalada o no.

¡Aquí le mostramos cómo empezar!

Configure un nuevo proyecto de Firebase e instale el SDK de Dynamic Links en su aplicación.

La instalación del SDK de Dynamic Links permite que Firebase transmita datos sobre Dynamic Link a la aplicación, incluso después de que el usuario instala la aplicación.

Ahora es el momento de configurar los enlaces que los usuarios pueden enviar a sus amigos. No se preocupe si los amigos de sus usuarios aún no tienen la aplicación instalada; Dynamic Links puede encargarse de eso por usted.

Para cada elemento de contenido que desee compartir, cree un vínculo dinámico .

Cuando cree el vínculo dinámico, deberá proporcionar una URL HTTP o HTTPS como parámetro de link que se usará para identificar el contenido que está compartiendo. Si tiene un sitio web con contenido equivalente, debe usar las URL de su sitio web. Esto garantizará que estos enlaces se muestren correctamente en una plataforma que no admita Dynamic Links, como un navegador de escritorio. Por ejemplo:

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

También puede agregar información adicional a la carga útil de datos agregando parámetros codificados en URL, por ejemplo, para indicar que el enlace está destinado a un usuario en particular, como en una invitación a un juego.

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 compartir estos vínculos, es posible que desee utilizar la API de acortamiento de URL de Firebase Dynamic Links para generar URL de apariencia más amigable. Un enlace dinámico breve se parece al siguiente ejemplo:

https://example.page.link/WXYZ

Independientemente del enlace que utilice, cuando los usuarios abran Dynamic Link en su dispositivo, la aplicación especificada por el parámetro apn (en Android) o los parámetros ibi e isi (en iOS) llevará a los usuarios a Play Store o App Store para instalar la aplicación. si no está ya instalado. Luego, cuando la aplicación se instala y abre, la URL especificada en el parámetro 'enlace' se pasa a la aplicación.

Primero, eche un vistazo a este ejemplo simple de una aplicación de chat basada en salas como Hangouts que genera enlaces para invitar a personas a las salas de chat.

iOS

chat app screenshotchat app screenshot with share sheet

Androide

chat app screenshotchat app screenshot with share sheet

Rápido

Nota: Este producto de Firebase no está disponible en objetivos macOS, Mac Catalyst, tvOS o 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
}

C objetivo

Nota: Este producto de Firebase no está disponible en objetivos macOS, Mac Catalyst, tvOS o 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
}

Una vez que tenga un enlace dinámico, puede agregar un botón de compartir a su interfaz de usuario que iniciará el flujo estándar de uso compartido de la plataforma:

Rápido

Nota: Este producto de Firebase no está disponible en objetivos macOS, Mac Catalyst, tvOS o 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)
}

C objetivo

Nota: Este producto de Firebase no está disponible en objetivos macOS, Mac Catalyst, tvOS o 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"))
}

En este ejemplo, la interfaz de usuario compartida predeterminada presenta automáticamente una lista de aplicaciones para compartir el enlace, por lo que es algo que puede configurar en su propia aplicación con solo unas pocas líneas de código.

En lugar de que el usuario seleccione contactos y redacte el mensaje en su aplicación, estas acciones se delegan a la aplicación que elijan en el cuadro de diálogo para compartir. Además, delegar el uso compartido a otras aplicaciones significa que no tiene que pedirle al usuario permisos de contactos y permite a los usuarios seleccionar de una lista de contactos ampliada dentro de la aplicación elegida. Para facilitar mejor el intercambio social, puede agregar metadatos de vista previa de redes sociales a su enlace dinámico que se mostrará junto con el enlace en los principales canales sociales.

A veces, sin embargo, el simple envío de un enlace sin texto no es suficiente para una referencia convincente. Al acompañar el enlace con un mensaje corto y, si es posible, una presentación más rica, los usuarios pueden comprender la propuesta de valor de la referencia cuando la reciben:

iOS

rewarded referral screenshotrewarded referral screenshot with share sheet

Androide

rewarded referral screenshotrewarded referral screenshot with share sheet

Aunque esto es más complejo que el último ejemplo, el enfoque será más o menos el mismo. En esta pantalla hay un gráfico grande con la propuesta de valor de la invitación y botones para compartir en los principales canales sociales. Hay cierta redundancia en este flujo de interfaz de usuario: algunos canales de uso compartido se presentan individualmente para permitir una personalización de mensajes más específica del canal, como agregar una línea de asunto a las invitaciones por correo electrónico. En este menú de invitación, nosotros:

  • Presente correos electrónicos, mensajes de texto y copie botones para compartir enlaces, y personalice sus mensajes apropiadamente. El correo electrónico incluirá un asunto y puede incluir un cuerpo más largo con saltos de línea, imágenes y espacios en blanco; el texto debe incluir un cuerpo más corto con saltos de línea, pero con pocos espacios en blanco y sin imágenes; y la copia de enlaces debería simplemente copiar el enlace y nada más.
  • Use la interfaz de usuario compartida del sistema para todo lo demás, incluido un breve mensaje de invitación para acompañar el enlace.
  • Enlace profundo a través de un esquema de URL o enlace universal a otra aplicación que tenga una lógica especial para manejar las invitaciones de su aplicación. Esto no funcionará fuera de una asociación entre su organización y la otra aplicación, y probablemente no sea una opción para organizaciones más pequeñas. Dicho esto, algunas aplicaciones pueden documentar públicamente su comportamiento de vinculación universal/profunda. Implementaremos una versión ficticia de esto en nuestra muestra.

Primero, defina un tipo de contenido de invitación, que encapsule solo la información en una invitación y no contenga ninguna funcionalidad. De esta manera, puede comenzar con los tipos de datos y pensar en su código en términos de cómo reúne esos datos.

Rápido

Nota: Este producto de Firebase no está disponible en objetivos macOS, Mac Catalyst, tvOS o 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

}

C objetivo

Nota: Este producto de Firebase no está disponible en objetivos macOS, Mac Catalyst, tvOS o 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
)

El único dato requerido aquí es la URL, sin la cual no puede invitar a los usuarios a su aplicación. Los otros datos están claramente estructurados para enviar correos electrónicos, lo que los hace un poco incómodos en algunos otros casos: cuando se envía una invitación sobre el texto, la propaganda que acompaña al enlace puede leerse de manera similar al asunto de un correo electrónico, pero cuando se comparte en las redes sociales. el enlace que acompaña al texto podría parecerse más al cuerpo de un correo electrónico. Tendrá que experimentar con esto usted mismo para encontrar el mejor equilibrio para su aplicación y, si no está seguro, siempre puede usar un servicio como Remote Config para permitirle cambiar los valores de texto después del lanzamiento de la aplicación.

Rápido

Nota: Este producto de Firebase no está disponible en objetivos macOS, Mac Catalyst, tvOS o 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()

}

C objetivo

Nota: Este producto de Firebase no está disponible en objetivos macOS, Mac Catalyst, tvOS o 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) {
        // ...
    }
}

Ahora todo lo que queda es conectar esto a un componente de interfaz de usuario de su elección. Para ver la implementación completa de este flujo de invitación, consulte los ejemplos en GitHub para iOS y Android .

Todos estos son métodos para permitir que sus usuarios envíen invitaciones a sus amigos, que es la solución de invitación más ligera. Muchas aplicaciones populares también entregan invitaciones mediante el envío de correos electrónicos a través de su propio backend, lo que requiere la integración de un servicio de envío de correos, pero ofrece una serie de beneficios que de otro modo no estarían disponibles con solo algunos inconvenientes menores.

Ventajas:

  • Habilita correos electrónicos con marcado complejo que su usuario no puede modificar antes de enviarlos.
  • Permite un seguimiento/análisis más granular (es decir, enviar éxitos y fallas en su backend).

Contras:

  • Correos electrónicos con más probabilidades de ser marcados como spam
  • Requiere integración con un servicio de entrega de correo electrónico
  • Requiere permisos de contactos en la aplicación

En general, enviar invitaciones a través de su propio servicio de entrega de correo electrónico brinda una experiencia de invitación más consistente y potencialmente más rica a costa de la versatilidad.

Abra el contenido vinculado en su aplicación

Finalmente, debe recibir el enlace que se pasa a su aplicación para que pueda mostrar el contenido vinculado al destinatario. Esto es fácil con el SDK de Dynamic Links:

iOS

En iOS, recibe Dynamic Link implementando el método application:continueUserActivity:restorationHandler: En el controlador de restauración, puede obtener Dynamic Link llamando a handleUniversalLink:completion: . Si se pasó un Dynamic Link a su aplicación, puede obtenerlo de la propiedad url de FIRDynamicLink . Por ejemplo:

C objetivo

Nota: Este producto de Firebase no está disponible en objetivos macOS, Mac Catalyst, tvOS o watchOS.
[[FIRDynamicLinks dynamicLinks]
    handleUniversalLink:userActivity.webpageURL
             completion:^(FIRDynamicLink * _Nullable dynamicLink,
                          NSError * _Nullable error) {
      NSString *link = dynamicLink.url;
      BOOL strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong;
      // ...
    }];

Rápido

Nota: Este producto de Firebase no está disponible en objetivos macOS, Mac Catalyst, tvOS o watchOS.
FIRDynamicLinks.dynamicLinks()?.handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
    let link = dynamicLink.url
    let strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong
    // ...
}

Además, debe llamar a dynamicLinkFromCustomSchemeURL: en el método application:openURL:options: para recibir Dynamic Links pasados ​​a su aplicación como URL de esquema personalizado. Por ejemplo:

C objetivo

Nota: Este producto de Firebase no está disponible en objetivos macOS, Mac Catalyst, tvOS o watchOS.
FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
if (dynamicLink) {
  NSString *link = dynamicLink.url;
  BOOL strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong;
  // ...
  return YES;
}

Rápido

Nota: Este producto de Firebase no está disponible en objetivos macOS, Mac Catalyst, tvOS o watchOS.
let dynamicLink = FIRDynamicLinks.dynamicLinks()?.dynamicLinkFromCustomSchemeURL(url)
if let dynamicLink = dynamicLink {
  let link = dynamicLink.url
  let strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong
  // ...
  return true
}

Ahora que tiene el valor del parámetro de link , puede mostrar el contenido vinculado al destinatario o procesar los datos especificados por el parámetro de alguna otra manera. Una biblioteca de enrutamiento de URL como JLRoutes puede ayudar con esta tarea.

Si recibe un enlace destinado a un destinatario específico, asegúrese de que la confianza de coincidencia del enlace dinámico sea strong antes de ejecutar cualquier lógica específica del usuario.

Androide

En Android, utiliza el método getDynamicLink() para obtener datos de 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
                // ...
            }
        }

Ahora que tiene el valor del parámetro de link , puede mostrar el contenido vinculado al destinatario o procesar los datos especificados por el parámetro de alguna otra manera. Una biblioteca de enrutamiento de URL puede ayudar con esta tarea.