Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Rinvii di ricompensa

Uno dei modi più efficaci per ottenere nuovi utenti è attraverso i referral degli utenti. Puoi utilizzare Dynamic Links insieme a Realtime Database e Cloud Functions for Firebase per incoraggiare i tuoi utenti a invitare i loro amici offrendo ricompense in-app per referral riusciti sia al referrer che al destinatario.

Vantaggi chiave

  • Accelera la crescita fornendo un incentivo ai tuoi utenti per invitare i loro 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, ritardare 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 Dynamic Links SDK

Configura un nuovo progetto Firebase e installa Dynamic Links SDK nella tua app. ( iOS , Android , C ++ , Unity ). L'installazione di Dynamic Links SDK consente a Firebase di trasmettere i dati su Dynamic Link all'app, anche dopo che l'utente ha installato l'app. Senza l'SDK, non è possibile connettere un utente post-installazione con un clic pre-installazione.

Per creare un invito, creare prima 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 dal tuo utente esistente.

Esistono molti modi per formattare questi payload dei parametri di link e collegarli alla tua app. Un modo semplice è 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 link dinamici adatti per l'inclusione in un invito, puoi utilizzare l'API Dynamic Link Builder:

iOS (Swift)

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
}

Giava

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

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

Invia gli inviti

Ora che hai creato il collegamento, 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 tramite posta elettronica:

iOS (Swift)

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)

Giava

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

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)
intent.data = 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(packageManager) != null) {
    startActivity(intent)
}

Recupera le informazioni di riferimento 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 referral 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 i criteri di ricompensa non vengono soddisfatti, è necessario tenere traccia delle informazioni sul premio ottenute dal collegamento dinamico.

Un modo per tenere traccia di queste informazioni è accedere all'utente in modo anonimo e memorizzare i 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:

iOS (Swift)

func application(_ app: UIApplication, open url: URL, options:
    [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
  if let isDynamicLink = DynamicLinks.dynamicLinks()?.shouldHandleDynamicLink(fromCustomSchemeURL: url),
      isDynamicLink {
    let dynamicLink = DynamicLinks.dynamicLinks()?.dynamicLink(fromCustomSchemeURL: url)
    return handleDynamicLink(dynamicLink)
  }
  // Handle incoming URL with other methods as necessary
  // ...
  return false
}

@available(iOS 8.0, *)
func application(_ application: UIApplication,
    continue userActivity: NSUserActivity,
    restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
  guard let dynamicLinks = DynamicLinks.dynamicLinks() else { return false }
  let handled = dynamicLinks.handleUniversalLink(userActivity.webpageURL!) { (dynamicLink, error) in
    if (dynamicLink != nil) && !(error != nil) {
      self.handleDynamicLink(dynamicLink)
    }
  }
  if !handled {
    // Handle incoming URL with other methods as necessary
    // ...
  }
  return handled
}

func handleDynamicLink(_ dynamicLink: DynamicLink?) -> Bool {
  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.
        }
      }
    }
  }
  return true
}

Giava

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

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

Quindi, quando il destinatario dell'invito decide di creare un account, è possibile 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 email e una password:

iOS (Swift)

let credential = EmailAuthProvider.credential(withEmail: email, password: password)

Giava

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

Kotlin + KTX

val credential = EmailAuthProvider.getCredential(email, password)

Quindi, collega questa credenziale all'account anonimo:

iOS (Swift)

if let user = Auth.auth().currentUser {
  user.link(with: credential) { (user, error) in
    // Complete any post sign-up tasks here.
  }
}

Giava

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

Kotlin + KTX

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

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

Concedi premi al referente e al destinatario

Ora che hai recuperato e salvato i dati dell'invito dal collegamento dinamico, puoi concedere i premi referral al referrer e al destinatario ogni volta che i criteri che desideri richiedere sono stati soddisfatti.

Sebbene tu possa scrivere nel Realtime Database dalla tua app client, spesso vorrai consentire solo l'accesso in lettura ai dati come la valuta in-app dalle tue app ed eseguire operazioni di scrittura solo dal tuo back-end. Questo backend potrebbe essere qualsiasi sistema in grado di eseguire Firebase Admin SDK, 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 la ricompensa per l'iscrizione, distribuire una funzione che controlla la creazione di una specifica chiave del database in tempo reale e garantisce la ricompensa 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 iscrive, attiva questa funzione creando la chiave del database in tempo reale. Ad esempio, attiva la funzione nel ascoltatore di successo di linkWithCredential , che hai creato nel passaggio precedente:

iOS (Swift)

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

Giava

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

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

Per concedere una ricompensa al referrer quando il destinatario raggiunge il livello 5, distribuisci 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, concedi la ricompensa:

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.