Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Ottieni nuovi utenti per la tua app consentendo agli utenti di condividere i contenuti della tua app

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

Uno dei modi più efficaci per convincere nuovi utenti a installare la tua app è consentire agli utenti di condividere i contenuti della tua app con i loro amici. Con i collegamenti dinamici, puoi creare un'esperienza di condivisione da utente a utente eccezionale: gli utenti che ricevono consigli sui contenuti dai loro amici possono fare clic su un collegamento ed essere indirizzati direttamente al contenuto condiviso nella tua app, anche se devono accedere all'app Store o Google Play Store per installare prima la tua app.

Combinando la viscosità dei referral degli utenti e la persistenza dei link dinamici, puoi creare funzionalità di condivisione e referral da utente a utente che attirano nuovi utenti attirandoli direttamente sui contenuti della tua app o offrendo promozioni a vantaggio reciproco del referrer e del referral .

Vantaggi chiave

  • I nuovi utenti che aprono la tua app per la prima volta ottengono un'esperienza di prima esecuzione personalizzata che viene contestualizzata in base a ciò che il loro amico desiderava condividere con loro. Ad esempio, puoi visualizzare il contenuto che è stato condiviso con loro o connetterli automaticamente con l'amico che li ha invitati.
  • Semplifica la condivisione di contenuti con i propri amici su piattaforme da parte degli utenti, indipendentemente dal fatto che i loro amici abbiano installato o meno la tua app.

Ecco come iniziare!

Configura un nuovo progetto Firebase e installa l'SDK di Dynamic Links nella tua app.

L'installazione dell'SDK di Dynamic Links consente a Firebase di trasmettere i dati relativi a Dynamic Link all'app, anche dopo che l'utente ha installato l'app.

Ora è il momento di impostare i collegamenti che gli utenti possono inviare ai propri amici. Non preoccuparti se gli amici dei tuoi utenti non hanno ancora installato l'app; Dynamic Links può occuparsene per te.

Per ogni elemento di contenuto che desideri rendere condivisibile, crea un collegamento dinamico .

Quando crei il collegamento dinamico, dovrai fornire un URL HTTP o HTTPS come parametro di link che verrà utilizzato per identificare il contenuto che stai condividendo. Se hai un sito web con contenuti equivalenti, dovresti utilizzare gli URL del tuo sito web. Ciò assicurerà che questi collegamenti vengano visualizzati correttamente su una piattaforma che non supporta i collegamenti dinamici, ad esempio un browser desktop. Ad esempio:

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

Puoi anche aggiungere ulteriori informazioni al payload dei dati aggiungendo parametri con codifica URL, ad esempio per indicare che il collegamento è destinato a un determinato utente, ad esempio in un invito a un gioco.

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

Prima di condividere questi collegamenti, potresti voler utilizzare l' API di abbreviazione degli URL di Firebase Dynamic Links per generare URL dall'aspetto più semplice. Un breve collegamento dinamico è simile al seguente esempio:

https://example.page.link/WXYZ

Indipendentemente dal collegamento utilizzato, quando gli utenti aprono il collegamento dinamico sul proprio dispositivo, l'app specificata dal parametro apn (su Android) o dai parametri ibi e isi (su iOS) indirizzerà gli utenti al Play Store o all'App Store per installare l'app se non è già installato. Quindi, quando l'app viene installata e aperta, l'URL specificato nel parametro 'link' viene passato all'app.

Innanzitutto, dai un'occhiata a questo semplice esempio di un'app di chat basata su room come Hangouts che genera collegamenti per invitare persone nelle chat room.

iOS

chat app screenshotchat app screenshot with share sheet

Androide

chat app screenshotchat app screenshot with share sheet

Rapido

Nota: questo prodotto Firebase non è disponibile su target 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
}

Obiettivo-C

Nota: questo prodotto Firebase non è disponibile su target 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;
}

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

Una volta che hai un collegamento dinamico, puoi aggiungere un pulsante di condivisione alla tua interfaccia utente che avvierà il flusso di condivisione della piattaforma standard:

Rapido

Nota: questo prodotto Firebase non è disponibile su target 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)
}

Obiettivo-C

Nota: questo prodotto Firebase non è disponibile su target 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];
}

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

In questo esempio, l'interfaccia utente di condivisione predefinita presenta automaticamente un elenco di app per la condivisione del collegamento, quindi è qualcosa che puoi configurare nella tua app con poche righe di codice.

Anziché consentire all'utente di selezionare i contatti e comporre il messaggio nella tua app, queste azioni vengono delegate all'app che scelgono dalla finestra di dialogo di condivisione. Inoltre, delegare la condivisione ad altre app significa che non è necessario chiedere all'utente le autorizzazioni per i contatti e consente agli utenti di selezionare da un elenco di contatti espanso all'interno dell'app prescelta. Per facilitare al meglio la condivisione sui social, puoi aggiungere i metadati di anteprima dei social media al tuo link dinamico che verrà visualizzato insieme al link nei principali canali social.

A volte, però, il semplice invio di un semplice collegamento senza testo non è sufficiente per un rinvio convincente. Accompagnando il link con un breve messaggio e, se possibile, una presentazione più ricca, gli utenti possono comprendere la proposta di valore del referral quando lo ricevono:

iOS

rewarded referral screenshotrewarded referral screenshot with share sheet

Androide

rewarded referral screenshotrewarded referral screenshot with share sheet

Sebbene questo sia più complesso dell'ultimo esempio, l'approccio sarà più o meno lo stesso. Su questa schermata c'è una grande grafica con la proposta di valore dell'invito e pulsanti per la condivisione sui principali canali social. C'è una certa ridondanza in questo flusso dell'interfaccia utente: alcuni canali di condivisione sono presentati individualmente per consentire una personalizzazione dei messaggi più specifica del canale, come l'aggiunta di una riga dell'oggetto agli inviti e-mail. In questo menu di invito, noi:

  • Presenta e-mail, messaggi di testo e copia i pulsanti di condivisione del collegamento e personalizza i loro messaggi in modo appropriato. L'e-mail includerà un oggetto e può includere un corpo più lungo con interruzioni di riga, immagini e spazi bianchi; il testo dovrebbe includere un corpo più corto con interruzioni di riga ma pochi spazi bianchi e nessuna immagine; e la copia del collegamento dovrebbe semplicemente copiare il collegamento e nient'altro.
  • Utilizza l'interfaccia utente di condivisione del sistema per tutto il resto, incluso un breve messaggio di invito per accompagnare il collegamento.
  • Collegamento diretto tramite schema URL o collegamento universale a un'altra app che ha una logica speciale per la gestione degli inviti della tua app. Questo non funzionerà al di fuori di una partnership tra la tua organizzazione e l'altra app e probabilmente non è un'opzione per le organizzazioni più piccole. Detto questo, alcune app potrebbero documentare pubblicamente il loro comportamento di collegamento universale/profondo. Implementeremo una versione fittizia di questo nel nostro esempio.

Innanzitutto, definisci un tipo di contenuto di invito, che incapsula solo le informazioni in un invito e non contiene alcuna funzionalità. In questo modo, puoi iniziare con i tipi di dati e pensare al tuo codice in termini di come mette insieme quei dati.

Rapido

Nota: questo prodotto Firebase non è disponibile su target 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

}

Obiettivo-C

Nota: questo prodotto Firebase non è disponibile su target 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

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

}

L'unico dato richiesto qui è l'URL, senza il quale non puoi invitare gli utenti alla tua app. Gli altri dati sono chiaramente strutturati per l'invio di e-mail, il che li rende un po' scomodi in alcuni altri casi: quando si invia un invito tramite testo, il blurb che accompagna il collegamento potrebbe leggere in modo simile all'oggetto di un'e-mail, ma quando si condivide sui social media il collegamento che accompagna il testo potrebbe essere più simile al corpo di un'e-mail. Dovrai sperimentare tu stesso per trovare il miglior equilibrio per la tua app e, se non sei sicuro, puoi sempre utilizzare un servizio come Remote Config per consentirti di modificare i valori del testo dopo l'avvio dell'app.

Rapido

Nota: questo prodotto Firebase non è disponibile su target 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()

}

Obiettivo-C

Nota: questo prodotto Firebase non è disponibile su target 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

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

}

Ora non resta che collegarlo a un componente dell'interfaccia utente di tua scelta. Per l'implementazione completa di questo flusso di invito, vedere gli esempi su GitHub per iOS e Android .

Questi sono tutti metodi per consentire ai tuoi utenti di inviare inviti ai loro amici, che è la soluzione di invito più leggera. Molte app popolari inviano anche inviti inviando e-mail tramite il proprio back-end, che richiede l'integrazione di un servizio di invio di posta, ma offre una serie di vantaggi altrimenti non disponibili con solo alcuni piccoli inconvenienti.

Professionisti:

  • Abilita le email con markup complesso che non può essere modificato dall'utente prima dell'invio.
  • Consente un monitoraggio/analisi più granulare (ovvero invia successi e fallimenti sul tuo back-end).

Contro:

  • E-mail che hanno maggiori probabilità di essere contrassegnate come spam
  • Richiede l'integrazione con un servizio di consegna e-mail
  • Richiede le autorizzazioni dei contatti in-app

In genere, l'invio di inviti tramite il proprio servizio di consegna e-mail offre un'esperienza di invito più coerente e potenzialmente più ricca a scapito della versatilità.

Apri il contenuto collegato nella tua app

Infine, devi ricevere il link passato alla tua app in modo da poter visualizzare il contenuto collegato al destinatario. Questo è facile utilizzando l'SDK di Dynamic Links:

iOS

Su iOS, ricevi il collegamento dinamico implementando il metodo application:continueUserActivity:restorationHandler: Nel gestore del ripristino, puoi ottenere il collegamento dinamico chiamando handleUniversalLink:completion: . Se un collegamento dinamico è stato passato alla tua app, puoi ottenerlo dalla proprietà url di FIRDynamicLink . Per esempio:

Obiettivo-C

Nota: questo prodotto Firebase non è disponibile su target 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;
      // ...
    }];

Rapido

Nota: questo prodotto Firebase non è disponibile su target macOS, Mac Catalyst, tvOS o watchOS.
FIRDynamicLinks.dynamicLinks()?.handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
    let link = dynamicLink.url
    let strongMatch = dynamicLink.matchConfidence == FIRDynamicLinkMatchConfidenceStrong
    // ...
}

Inoltre, devi chiamare dynamicLinkFromCustomSchemeURL: nel metodo application:openURL:options: per ricevere i collegamenti dinamici passati alla tua app come URL di schemi personalizzati. Per esempio:

Obiettivo-C

Nota: questo prodotto Firebase non è disponibile su target 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;
}

Rapido

Nota: questo prodotto Firebase non è disponibile su target 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
}

Ora che si dispone del valore del parametro di link , è possibile visualizzare il contenuto collegato al destinatario o elaborare i dati specificati dal parametro in qualche altro modo. Una libreria di instradamento degli URL come JLRoutes può aiutare con questa attività.

Se stai ricevendo un collegamento destinato a un destinatario specifico, assicurati che l'attendibilità della corrispondenza del collegamento dinamico sia strong prima di eseguire qualsiasi logica specifica dell'utente.

Androide

Su Android, utilizzi il metodo getDynamicLink() per ottenere i dati dal collegamento dinamico:

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

Ora che si dispone del valore del parametro di link , è possibile visualizzare il contenuto collegato al destinatario o elaborare i dati specificati dal parametro in qualche altro modo. Una libreria di routing degli URL può aiutare con questa attività.