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 premiando i referral degli utenti

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

Uno dei modi più efficaci per ottenere nuovi utenti è attraverso i referral degli utenti. Puoi utilizzare i collegamenti dinamici insieme al database in tempo reale e alle funzioni cloud per Firebase per incoraggiare i tuoi utenti a invitare i loro amici offrendo premi in-app per i referral riusciti sia al referrer che al destinatario.

Vantaggi chiave

  • Accelera la crescita fornendo un incentivo ai tuoi utenti affinché invitino i propri amici.
  • I link di invito funzionano su tutte le piattaforme.
  • I nuovi utenti che aprono la tua app per la prima volta ottengono un'esperienza di prima esecuzione personalizzabile per loro. Ad esempio, puoi connetterli automaticamente con l'amico che li ha invitati.
  • Facoltativamente, ritarda la concessione dei premi fino a quando i nuovi utenti non completano alcune attività introduttive, come il completamento di un tutorial.

Ecco come iniziare!

Configura Firebase e l'SDK di Dynamic Links

Configura un nuovo progetto Firebase e installa l'SDK di Dynamic Links nella tua app. ( iOS , Android , C++ , Unity ). 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. Senza l'SDK, non c'è modo di connettere un utente post-installazione con un clic pre-installazione.

Per creare un invito, creare innanzitutto il collegamento che il destinatario apre per accettare l'invito. Successivamente, includerai questo collegamento nel testo dell'invito. Quando un destinatario dell'invito installa la tua app aprendo il collegamento, può ottenere un'esperienza di prima esecuzione personalizzata, inclusa la ricezione di un premio in-app.

Questo collegamento di invito è un collegamento dinamico con un valore di parametro di link che indica che proviene dall'utente esistente.

Esistono molti modi per formattare questi payload dei parametri di link e collegarli alla tua app. Un modo semplice consiste nello specificare l'ID dell'account utente del mittente in un parametro di query come nell'esempio seguente:

https://mygame.example.com/?invitedby=SENDER_UID

Quindi, per creare collegamenti dinamici adatti all'inclusione in un invito, puoi utilizzare l'API Dynamic Link Builder:

Rapido

Nota: questo prodotto Firebase non è disponibile su target macOS, Mac Catalyst, tvOS o watchOS.
guard let uid = Auth.auth().currentUser?.uid else { return }
let link = URL(string: "https://mygame.example.com/?invitedby=\(uid)")
let referralLink = DynamicLinkComponents(link: link!, domain: "example.page.link")

referralLink.iOSParameters = DynamicLinkIOSParameters(bundleID: "com.example.ios")
referralLink.iOSParameters?.minimumAppVersion = "1.0.1"
referralLink.iOSParameters?.appStoreID = "123456789"

referralLink.androidParameters = DynamicLinkAndroidParameters(packageName: "com.example.android")
referralLink.androidParameters?.minimumVersion = 125

referralLink.shorten { (shortURL, warnings, error) in
  if let error = error {
    print(error.localizedDescription)
    return
  }
  self.invitationUrl = shortURL
}

Kotlin+KTX

val user = Firebase.auth.currentUser!!
val uid = user.uid
val invitationLink = "https://mygame.example.com/?invitedby=$uid"
Firebase.dynamicLinks.shortLinkAsync {
    link = Uri.parse(invitationLink)
    domainUriPrefix = "https://example.page.link"
    androidParameters("com.example.android") {
        minimumVersion = 125
    }
    iosParameters("com.example.ios") {
        appStoreId = "123456789"
        minimumVersion = "1.0.1"
    }
}.addOnSuccessListener { shortDynamicLink ->
    mInvitationUrl = shortDynamicLink.shortLink
    // ...
}

Java

FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String uid = user.getUid();
String link = "https://mygame.example.com/?invitedby=" + uid;
FirebaseDynamicLinks.getInstance().createDynamicLink()
        .setLink(Uri.parse(link))
        .setDomainUriPrefix("https://example.page.link")
        .setAndroidParameters(
                new DynamicLink.AndroidParameters.Builder("com.example.android")
                        .setMinimumVersion(125)
                        .build())
        .setIosParameters(
                new DynamicLink.IosParameters.Builder("com.example.ios")
                        .setAppStoreId("123456789")
                        .setMinimumVersion("1.0.1")
                        .build())
        .buildShortDynamicLink()
        .addOnSuccessListener(new OnSuccessListener<ShortDynamicLink>() {
            @Override
            public void onSuccess(ShortDynamicLink shortDynamicLink) {
                mInvitationUrl = shortDynamicLink.getShortLink();
                // ...
            }
        });

Invia gli inviti

Ora che hai creato il link, puoi includerlo in un invito. L'invito può essere un'e-mail, un messaggio SMS o qualsiasi altro mezzo, a seconda di ciò che è più appropriato per la tua app e il tuo pubblico.

Ad esempio, per inviare un invito via e-mail:

Rapido

Nota: questo prodotto Firebase non è disponibile su target macOS, Mac Catalyst, tvOS o watchOS.
guard let referrerName = Auth.auth().currentUser?.displayName else { return }
let subject = "\(referrerName) wants you to play MyExampleGame!"
let invitationLink = invitationUrl?.absoluteString
let msg = "<p>Let's play MyExampleGame together! Use my <a href=\"\(invitationLink)\">referrer link</a>!</p>"

if !MFMailComposeViewController.canSendMail() {
  // Device can't send email
  return
}
let mailer = MFMailComposeViewController()
mailer.mailComposeDelegate = self
mailer.setSubject(subject)
mailer.setMessageBody(msg, isHTML: true)
myView.present(mailer, animated: true, completion: nil)

Kotlin+KTX

val referrerName = Firebase.auth.currentUser?.displayName
val subject = String.format("%s wants you to play MyExampleGame!", referrerName)
val invitationLink = mInvitationUrl.toString()
val msg = "Let's play MyExampleGame together! Use my referrer link: $invitationLink"
val msgHtml = String.format("<p>Let's play MyExampleGame together! Use my " +
        "<a href=\"%s\">referrer link</a>!</p>", invitationLink)

val intent = Intent(Intent.ACTION_SENDTO).apply {
    data = Uri.parse("mailto:") // only email apps should handle this
    putExtra(Intent.EXTRA_SUBJECT, subject)
    putExtra(Intent.EXTRA_TEXT, msg)
    putExtra(Intent.EXTRA_HTML_TEXT, msgHtml)
}
intent.resolveActivity(packageManager)?.let {
    startActivity(intent)
}

Java

String referrerName = FirebaseAuth.getInstance().getCurrentUser().getDisplayName();
String subject = String.format("%s wants you to play MyExampleGame!", referrerName);
String invitationLink = mInvitationUrl.toString();
String msg = "Let's play MyExampleGame together! Use my referrer link: "
        + invitationLink;
String msgHtml = String.format("<p>Let's play MyExampleGame together! Use my "
        + "<a href=\"%s\">referrer link</a>!</p>", invitationLink);

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:")); // only email apps should handle this
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, msg);
intent.putExtra(Intent.EXTRA_HTML_TEXT, msgHtml);
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}

Recupera le informazioni sui referral nella tua app

Quando il destinatario dell'invito apre il link di riferimento, verrà indirizzato all'App Store o al Play Store per installare la tua app se non è già installata. Quindi, quando aprono la tua app per la prima volta, puoi recuperare le informazioni di riferimento che hai incluso nel collegamento dinamico e utilizzarle per applicare il premio.

Di solito, si desidera concedere premi di riferimento solo dopo che il destinatario dell'invito si è registrato o anche solo dopo che il nuovo utente ha completato alcune attività. Fino a quando non vengono soddisfatti i criteri di ricompensa, è necessario tenere traccia delle informazioni sulla ricompensa ottenute dal collegamento dinamico.

Un modo per tenere traccia di queste informazioni è l'accesso dell'utente in modo anonimo e l'archiviazione dei dati nel record del database in tempo reale dell'account anonimo. Quando il destinatario si iscrive e l'account anonimo viene convertito in un account permanente, il nuovo account avrà lo stesso UID dell'account anonimo e, di conseguenza, avrà accesso alle informazioni sulla ricompensa.

Ad esempio, per salvare l'UID del referrer dopo che il destinatario ha aperto la tua app:

Rapido

Nota: questo prodotto Firebase non è disponibile su target macOS, Mac Catalyst, tvOS o watchOS.
struct MyApplication: App {

  var body: some Scene {
    WindowGroup {
      VStack {
        Text("Example text")
      }
      .onOpenURL { url in
        if DynamicLinks.dynamicLinks()?.shouldHandleDynamicLink(fromCustomSchemeURL: url) ?? false {
        let dynamicLink = DynamicLinks.dynamicLinks()?.dynamicLink(fromCustomSchemeURL: url)
        handleDynamicLink(dynamicLink)
      }
      // Handle incoming URL with other methods as necessary
      // ...
      }
    }
  }
}

func handleDynamicLink(_ dynamicLink: DynamicLink?) {
  guard let dynamicLink = dynamicLink else { return false }
  guard let deepLink = dynamicLink.url else { return false }
  let queryItems = URLComponents(url: deepLink, resolvingAgainstBaseURL: true)?.queryItems
  let invitedBy = queryItems?.filter({(item) in item.name == "invitedby"}).first?.value
  let user = Auth.auth().currentUser
  // If the user isn't signed in and the app was opened via an invitation
  // link, sign in the user anonymously and record the referrer UID in the
  // user's RTDB record.
  if user == nil && invitedBy != nil {
    Auth.auth().signInAnonymously() { (user, error) in
      if let user = user {
        let userRecord = Database.database().reference().child("users").child(user.uid)
        userRecord.child("referred_by").setValue(invitedBy)
        if dynamicLink.matchConfidence == .weak {
          // If the Dynamic Link has a weak match confidence, it is possible
          // that the current device isn't the same device on which the invitation
          // link was originally opened. The way you handle this situation
          // depends on your app, but in general, you should avoid exposing
          // personal information, such as the referrer's email address, to
          // the user.
        }
      }
    }
  }
}

Kotlin+KTX

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // ...

    Firebase.dynamicLinks
            .getDynamicLink(intent)
            .addOnSuccessListener(this) { pendingDynamicLinkData ->
                // Get deep link from result (may be null if no link is found)
                var deepLink: Uri? = null
                if (pendingDynamicLinkData != null) {
                    deepLink = pendingDynamicLinkData.link
                }
                //
                // If the user isn't signed in and the pending Dynamic Link is
                // an invitation, sign in the user anonymously, and record the
                // referrer's UID.
                //
                val user = Firebase.auth.currentUser
                if (user == null &&
                        deepLink != null &&
                        deepLink.getBooleanQueryParameter("invitedby", false)) {
                    val referrerUid = deepLink.getQueryParameter("invitedby")
                    createAnonymousAccountWithReferrerInfo(referrerUid)
                }
            }
}

private fun createAnonymousAccountWithReferrerInfo(referrerUid: String?) {
    Firebase.auth
            .signInAnonymously()
            .addOnSuccessListener {
                // Keep track of the referrer in the RTDB. Database calls
                // will depend on the structure of your app's RTDB.
                val user = Firebase.auth.currentUser
                val userRecord = Firebase.database.reference
                        .child("users")
                        .child(user!!.uid)
                userRecord.child("referred_by").setValue(referrerUid)
            }
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // ...

    FirebaseDynamicLinks.getInstance()
            .getDynamicLink(getIntent())
            .addOnSuccessListener(this, new OnSuccessListener<PendingDynamicLinkData>() {
                @Override
                public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
                    // Get deep link from result (may be null if no link is found)
                    Uri deepLink = null;
                    if (pendingDynamicLinkData != null) {
                        deepLink = pendingDynamicLinkData.getLink();
                    }
                    //
                    // If the user isn't signed in and the pending Dynamic Link is
                    // an invitation, sign in the user anonymously, and record the
                    // referrer's UID.
                    //
                    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
                    if (user == null
                            && deepLink != null
                            && deepLink.getBooleanQueryParameter("invitedby", false)) {
                        String referrerUid = deepLink.getQueryParameter("invitedby");
                        createAnonymousAccountWithReferrerInfo(referrerUid);
                    }
                }
            });
}

private void createAnonymousAccountWithReferrerInfo(final String referrerUid) {
    FirebaseAuth.getInstance()
            .signInAnonymously()
            .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
                @Override
                public void onSuccess(AuthResult authResult) {
                    // Keep track of the referrer in the RTDB. Database calls
                    // will depend on the structure of your app's RTDB.
                    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
                    DatabaseReference userRecord =
                            FirebaseDatabase.getInstance().getReference()
                                    .child("users")
                                    .child(user.getUid());
                    userRecord.child("referred_by").setValue(referrerUid);
                }
            });
}

Quindi, quando il destinatario dell'invito decide di creare un account, puoi trasferire le informazioni di riferimento dall'account anonimo al nuovo account del destinatario dell'invito.

Innanzitutto, ottieni un oggetto AuthCredential utilizzando il metodo di accesso che l'invitato desidera utilizzare. Ad esempio, per accedere con un indirizzo e-mail e una password:

Rapido

Nota: questo prodotto Firebase non è disponibile su target macOS, Mac Catalyst, tvOS o watchOS.
let credential = EmailAuthProvider.credential(withEmail: email, password: password)

Kotlin+KTX

val credential = EmailAuthProvider.getCredential(email, password)

Java

AuthCredential credential = EmailAuthProvider.getCredential(email, password);

Quindi, collega questa credenziale all'account anonimo:

Rapido

Nota: questo prodotto Firebase non è disponibile su target macOS, Mac Catalyst, tvOS o watchOS.
if let user = Auth.auth().currentUser {
  user.link(with: credential) { (user, error) in
    // Complete any post sign-up tasks here.
  }
}

Kotlin+KTX

Firebase.auth.currentUser!!
        .linkWithCredential(credential)
        .addOnSuccessListener {
            // Complete any post sign-up tasks here.
        }

Java

FirebaseAuth.getInstance().getCurrentUser()
        .linkWithCredential(credential)
        .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                // Complete any post sign-up tasks here.
            }
        });

Il nuovo account permanente ha accesso a tutti i dati del premio che hai aggiunto all'account anonimo.

Assegna premi al referrer e al destinatario

Ora che hai recuperato e salvato i dati dell'invito dal Dynamic Link, puoi concedere i premi per il referral al referrer e al destinatario ogni volta che i criteri che vuoi richiedere sono stati soddisfatti.

Sebbene tu possa scrivere nel database in tempo reale dalla tua app client, spesso vorrai consentire solo l'accesso in lettura a dati come la valuta in-app dalle tue app ed eseguire operazioni di scrittura solo dal tuo back-end. Questo back-end potrebbe essere qualsiasi sistema in grado di eseguire l'SDK Firebase Admin, ma spesso è più semplice utilizzare Cloud Functions per eseguire queste attività.

Ad esempio, supponi di avere un gioco e di voler concedere una ricompensa in valuta di gioco al destinatario dopo che il destinatario si è registrato e al referrer dopo che il destinatario ha raggiunto il livello 5.

Per concedere il premio per la registrazione, implementa una funzione che controlla la creazione di una specifica chiave di Realtime Database e concede il premio quando lo è. Per esempio:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.grantSignupReward = functions.database.ref('/users/{uid}/last_signin_at')
    .onCreate(event => {
      var uid = event.params.uid;
      admin.database().ref(`users/${uid}/referred_by`)
        .once('value').then(function(data) {
          var referred_by_somebody = data.val();
          if (referred_by_somebody) {
            var moneyRef = admin.database()
                .ref(`/users/${uid}/inventory/pieces_of_eight`);
            moneyRef.transaction(function (current_value) {
              return (current_value || 0) + 50;
            });
          }
        });
    });

Quindi, quando un nuovo utente si registra, attiva questa funzione creando la chiave del database in tempo reale. Ad esempio, attiva la funzione nel listener di successo di linkWithCredential , che hai creato nel passaggio precedente:

Rapido

Nota: questo prodotto Firebase non è disponibile su target macOS, Mac Catalyst, tvOS o watchOS.
if let user = Auth.auth().currentUser {
  user.link(with: credential) { (user, error) in
    // Complete any post sign-up tasks here.

    // Trigger the sign-up reward function by creating the "last_signin_at" field.
    // (If this is a value you want to track, you would also update this field in
    // the success listeners of your Firebase Authentication signIn calls.)
    if let user = user {
      let userRecord = Database.database().reference().child("users").child(user.uid)
      userRecord.child("last_signin_at").setValue(ServerValue.timestamp())
    }
  }
}

Kotlin+KTX

Firebase.auth.currentUser!!
        .linkWithCredential(credential)
        .addOnSuccessListener {
            // Complete any post sign-up tasks here.

            // Trigger the sign-up reward function by creating the
            // "last_signin_at" field. (If this is a value you want to track,
            // you would also update this field in the success listeners of
            // your Firebase Authentication signIn calls.)
            val user = Firebase.auth.currentUser!!
            val userRecord = Firebase.database.reference
                    .child("users")
                    .child(user.uid)
            userRecord.child("last_signin_at").setValue(ServerValue.TIMESTAMP)
        }

Java

FirebaseAuth.getInstance().getCurrentUser()
        .linkWithCredential(credential)
        .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                // Complete any post sign-up tasks here.

                // Trigger the sign-up reward function by creating the
                // "last_signin_at" field. (If this is a value you want to track,
                // you would also update this field in the success listeners of
                // your Firebase Authentication signIn calls.)
                FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
                DatabaseReference userRecord =
                        FirebaseDatabase.getInstance().getReference()
                                .child("users")
                                .child(user.getUid());
                userRecord.child("last_signin_at").setValue(ServerValue.TIMESTAMP);
            }
        });

Per concedere una ricompensa al referrer quando il destinatario raggiunge il livello 5, implementa una funzione che controlla le modifiche al campo del level nei tuoi record utente. Se un utente è passato dal livello 4 al livello 5 e l'utente ha registrato un referrer, assegna il premio:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.rewardReferrals = functions.database.ref('/users/{uid}/level')
    .onUpdate(event => {
      var level = event.data.val();
      var prev_level = event.data.previous.val();
      if (prev_level == 4 && level == 5) {
        var referrerRef = event.data.ref.parent.child('referred_by');
        return referrerRef.once('value').then(function(data) {
          var referrerUid = data.val();
          if (referrerUid) {
            var moneyRef = admin.database()
                .ref(`/users/${referrerUid}/inventory/pieces_of_eight`);
            return moneyRef.transaction(function (current_value) {
              return (current_value || 0) + 50;
            });
          }
        });
      }
    });

Sia il referrer che il tuo nuovo utente hanno ora ricevuto i loro premi.