Inviter des utilisateurs à votre application

L'un des moyens les plus efficaces d'amener de nouveaux utilisateurs à installer votre application consiste à permettre à vos utilisateurs de partager le contenu de votre application avec leurs amis. Avec les liens dynamiques, vous pouvez créer une excellente expérience de partage d'utilisateur à utilisateur : les utilisateurs qui reçoivent des recommandations de contenu de la part de leurs amis peuvent cliquer sur un lien et être redirigés directement vers le contenu partagé dans votre application, même s'ils doivent accéder à l'application. Store ou Google Play Store pour installer votre application en premier.

En combinant l'adhérence des parrainages d'utilisateurs et la persistance des liens dynamiques, vous pouvez créer des fonctionnalités de partage et de parrainage d'utilisateur à utilisateur qui attirent de nouveaux utilisateurs en les attirant directement vers le contenu de votre application ou en proposant des promotions qui profitent mutuellement au référent et au parrainé. .

Avantages clés

  • Les nouveaux utilisateurs qui ouvrent votre application pour la première fois bénéficient d'une première expérience personnalisée qui est contextualisée en fonction de ce que leur ami voulait partager avec eux. Par exemple, vous pouvez afficher le contenu qui a été partagé avec eux ou les connecter automatiquement avec l'ami qui les a invités.
  • Permet aux utilisateurs de partager facilement du contenu avec leurs amis sur toutes les plateformes, que leurs amis aient ou non installé votre application.

Voici comment commencer !

Configurez un nouveau projet Firebase et installez le SDK Dynamic Links dans votre application.

L'installation du SDK Dynamic Links permet à Firebase de transmettre des données sur le lien dynamique à l'application, y compris après que l'utilisateur a installé l'application.

Il est maintenant temps de configurer les liens que les utilisateurs peuvent envoyer à leurs amis. Ne vous inquiétez pas si les amis de vos utilisateurs n'ont pas encore installé l'application ; Dynamic Links peut s'en charger pour vous.

Pour chaque élément de contenu que vous souhaitez partager, créez un lien dynamique .

Lorsque vous créez le lien dynamique, vous devez fournir une URL HTTP ou HTTPS comme paramètre de link qui sera utilisé pour identifier le contenu que vous partagez. Si vous avez un site Web avec un contenu équivalent, vous devez utiliser les URL de votre site Web. Cela garantira que ces liens s'affichent correctement sur une plate-forme qui ne prend pas en charge les liens dynamiques, comme un navigateur de bureau. Par exemple :

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

Vous pouvez également ajouter des informations supplémentaires à la charge utile des données en ajoutant des paramètres encodés en URL, par exemple, pour indiquer que le lien est destiné à un utilisateur particulier, comme dans une invitation à un jeu.

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

Avant de partager ces liens, vous souhaiterez peut-être utiliser l' API de raccourcissement d'URL Firebase Dynamic Links pour générer des URL plus conviviales. Un lien dynamique court ressemble à l'exemple suivant :

https://example.page.link/WXYZ

Quel que soit le lien que vous utilisez, lorsque les utilisateurs ouvrent le lien dynamique sur leur appareil, l'application spécifiée par le paramètre apn (sur Android) ou les paramètres ibi et isi (sur iOS) dirigera les utilisateurs vers le Play Store ou l'App Store pour installer l'application. s'il n'est pas déjà installé. Ensuite, lorsque l'application est installée et ouverte, l'URL spécifiée dans le paramètre 'link' est transmise à l'application.

Tout d'abord, jetez un œil à cet exemple simple d'une application de chat basée sur une salle comme Hangouts qui génère des liens pour inviter des personnes à des salles de chat.

iOS

chat app screenshotchat app screenshot with share sheet

Android

chat app screenshotchat app screenshot with share sheet

Rapide

Remarque : Ce produit Firebase n'est pas disponible sur les cibles 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
}

Objectif c

Remarque : Ce produit Firebase n'est pas disponible sur les cibles 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
}

Une fois que vous avez un lien dynamique, vous pouvez ajouter un bouton de partage à votre interface utilisateur qui lancera le flux de partage de plateforme standard :

Rapide

Remarque : Ce produit Firebase n'est pas disponible sur les cibles 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)
}

Objectif c

Remarque : Ce produit Firebase n'est pas disponible sur les cibles 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"))
}

Dans cet exemple, l'interface utilisateur de partage par défaut présente automatiquement une liste d'applications pour partager le lien, c'est donc quelque chose que vous pouvez configurer dans votre propre application avec seulement quelques lignes de code.

Plutôt que de demander à l'utilisateur de sélectionner des contacts et de composer le message dans votre application, ces actions sont déléguées à l'application qu'il choisit dans la boîte de dialogue de partage. De plus, la délégation du partage à d'autres applications signifie que vous n'avez pas à demander à l'utilisateur des autorisations de contacts et permet aux utilisateurs de sélectionner parmi une liste de contacts étendue dans l'application de leur choix. Pour mieux faciliter le partage sur les réseaux sociaux, vous pouvez ajouter à votre lien dynamique des métadonnées d'aperçu des médias sociaux qui seront affichées avec le lien dans les principaux canaux sociaux.

Parfois, cependant, le simple fait d'envoyer un lien nu sans texte n'est pas suffisant pour une référence convaincante. En accompagnant le lien d'un message court et, si possible, d'une présentation plus riche, les utilisateurs peuvent comprendre la proposition de valeur du filleul lorsqu'ils le reçoivent :

iOS

rewarded referral screenshotrewarded referral screenshot with share sheet

Android

rewarded referral screenshotrewarded referral screenshot with share sheet

Bien que ce soit plus complexe que le dernier exemple, l'approche sera plus ou moins la même. Sur cet écran, il y a un grand graphique avec la proposition de valeur de l'invitation et des boutons pour le partage sur les principaux canaux sociaux. Il y a une certaine redondance dans ce flux d'interface utilisateur : certains canaux de partage sont présentés individuellement pour permettre une personnalisation des messages plus spécifique au canal, comme l'ajout d'une ligne d'objet aux invitations par e-mail. Dans ce menu d'invitation, nous :

  • Présentez les boutons de partage de courrier électronique, de message texte et de copie de lien, et personnalisez leurs messages de manière appropriée. L'e-mail inclura un objet et peut inclure un corps plus long avec des sauts de ligne, des images et des espaces ; le texte doit inclure un corps plus court avec des sauts de ligne mais peu d'espaces et pas d'images ; et la copie de lien devrait simplement copier le lien et rien d'autre.
  • Utilisez l'interface utilisateur de partage du système pour tout le reste, y compris un court message d'invitation pour accompagner le lien.
  • Lien profond via un schéma d'URL ou un lien universel vers une autre application qui a une logique spéciale pour gérer les invitations de votre application. Cela ne fonctionnera pas en dehors d'un partenariat entre votre organisation et l'autre application, et n'est probablement pas une option pour les petites organisations. Cela dit, certaines applications peuvent documenter publiquement leur comportement de lien universel/profond. Nous en implémenterons une version factice dans notre exemple.

Tout d'abord, définissez un type de contenu d'invitation, qui encapsule uniquement les informations d'une invitation et ne contient aucune fonctionnalité. De cette façon, vous pouvez commencer par les types de données et réfléchir à votre code en termes de la manière dont il assemble ces données.

Rapide

Remarque : Ce produit Firebase n'est pas disponible sur les cibles 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

}

Objectif c

Remarque : Ce produit Firebase n'est pas disponible sur les cibles 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
)

La seule donnée requise ici est l'URL, sans laquelle vous ne pouvez pas inviter d'utilisateurs à rejoindre votre application. Les autres éléments de données sont clairement structurés pour envoyer des e-mails, ce qui les rend un peu gênants dans certains autres cas - lors de l'envoi d'une invitation par SMS, le texte de présentation accompagnant le lien peut se lire de la même manière qu'un sujet d'e-mail, mais lors du partage sur les réseaux sociaux le texte d'accompagnement du lien pourrait ressembler davantage à un corps d'e-mail. Vous devrez expérimenter cela vous-même pour trouver le meilleur équilibre pour votre application, et si vous n'êtes pas sûr, vous pouvez toujours utiliser un service comme Remote Config pour vous permettre de modifier les valeurs de texte après le lancement de l'application.

Rapide

Remarque : Ce produit Firebase n'est pas disponible sur les cibles 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()

}

Objectif c

Remarque : Ce produit Firebase n'est pas disponible sur les cibles 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) {
        // ...
    }
}

Maintenant, tout ce qui reste est de brancher ceci dans un composant d'interface utilisateur de votre choix. Pour la mise en œuvre complète de ce flux d'invitation, consultez les exemples sur GitHub pour iOS et Android .

Ce sont toutes des méthodes permettant à vos utilisateurs d'envoyer des invitations à leurs amis, ce qui est la solution d'invitation la plus légère. De nombreuses applications populaires proposent également des invitations en envoyant des e-mails via leur propre backend, ce qui nécessite l'intégration d'un service d'envoi de courrier, mais offre un certain nombre d'avantages qui ne sont pas disponibles autrement avec seulement quelques inconvénients mineurs.

Avantages:

  • Active les e-mails avec un balisage complexe qui ne peut pas être modifié par votre utilisateur avant l'envoi.
  • Permet un suivi / analyse plus granulaire (c'est-à-dire envoyer les succès et les échecs sur votre backend).

Les inconvénients:

  • Les e-mails sont plus susceptibles d'être signalés comme spam
  • Nécessite une intégration avec un service de livraison de courrier électronique
  • Nécessite des autorisations de contacts dans l'application

En règle générale, l'envoi d'invitations via votre propre service de livraison par e-mail offre une expérience d'invitation plus cohérente et potentiellement plus riche au détriment de la polyvalence.

Ouvrez le contenu lié dans votre application

Enfin, vous devez recevoir le lien transmis à votre application afin de pouvoir afficher le contenu lié au destinataire. C'est facile avec le SDK Dynamic Links :

iOS

Sur iOS, vous recevez le lien dynamique en implémentant la méthode application:continueUserActivity:restorationHandler: :. Dans le gestionnaire de restauration, vous pouvez obtenir le lien dynamique en appelant handleUniversalLink:completion: . Si un lien dynamique a été transmis à votre application, vous pouvez l'obtenir à partir de la propriété url du FIRDynamicLink . Par exemple:

Objectif c

Remarque : Ce produit Firebase n'est pas disponible sur les cibles 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;
      // ...
    }];

Rapide

Remarque : Ce produit Firebase n'est pas disponible sur les cibles macOS, Mac Catalyst, tvOS ou watchOS.
FIRDynamicLinks.dynamicLinks()?.handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
    let link = dynamicLink.url
    let strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong
    // ...
}

De plus, vous devez appeler dynamicLinkFromCustomSchemeURL: dans la méthode application:openURL:options: pour recevoir les liens dynamiques transmis à votre application en tant qu'URL de schéma personnalisé. Par exemple:

Objectif c

Remarque : Ce produit Firebase n'est pas disponible sur les cibles 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;
}

Rapide

Remarque : Ce produit Firebase n'est pas disponible sur les cibles 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
}

Maintenant que vous avez la valeur du paramètre de link , vous pouvez afficher le contenu lié au destinataire ou traiter les données spécifiées par le paramètre d'une autre manière. Une bibliothèque de routage d'URL telle que JLRoutes peut vous aider dans cette tâche.

Si vous recevez un lien destiné à un destinataire spécifique, assurez-vous que la confiance de correspondance du lien dynamique est strong avant d'exécuter une logique spécifique à l'utilisateur.

Android

Sur Android, vous utilisez la méthode getDynamicLink() pour obtenir les données du 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
                // ...
            }
        }

Maintenant que vous avez la valeur du paramètre de link , vous pouvez afficher le contenu lié au destinataire ou traiter les données spécifiées par le paramètre d'une autre manière. Une bibliothèque de routage d'URL peut vous aider dans cette tâche.