Google 致力于为黑人社区推动种族平等。查看具体举措
Cette page a été traduite par l'API Cloud Translation.
Switch to English

Références de récompense

L'un des moyens les plus efficaces d'attirer de nouveaux utilisateurs consiste à parrainer des utilisateurs. Vous pouvez utiliser les liens dynamiques avec la base de données en temps réel et les fonctions cloud pour Firebase pour encourager vos utilisateurs à inviter leurs amis en offrant des récompenses dans l'application pour les références réussies à la fois au parrain et au destinataire.

Avantages clés

  • Accélérez la croissance en incitant vos utilisateurs à inviter leurs amis.
  • Les liens d'invitation fonctionnent sur toutes les plates-formes.
  • Les nouveaux utilisateurs qui ouvrent votre application pour la première fois bénéficient d'une expérience de première exécution que vous personnalisez pour eux. Par exemple, vous pouvez les connecter automatiquement avec l'ami qui les a invités.
  • Vous pouvez éventuellement retarder l'octroi des récompenses jusqu'à ce que les nouveaux utilisateurs aient terminé une tâche d'introduction, comme la réalisation d'un didacticiel.

Voici comment commencer!

Configurer Firebase et le SDK Dynamic Links

Configurez un nouveau projet Firebase et installez le SDK Dynamic Links dans votre application. ( iOS , Android , C ++ , Unity ). L'installation du SDK Dynamic Links permet à Firebase de transmettre des données sur le lien dynamique à l'application, y compris après l'installation de l'application par l'utilisateur. Sans le SDK, il n'y a aucun moyen de connecter un utilisateur post-installation avec un clic de pré-installation.

Pour créer une invitation, créez d'abord le lien que le destinataire ouvre pour accepter l'invitation. Plus tard, vous incluerez ce lien dans le texte de l'invitation. Lorsqu'un destinataire de l'invitation installe votre application en ouvrant le lien, il peut bénéficier d'une expérience de première exécution personnalisée, notamment en recevant une récompense intégrée à l'application.

Ce lien d'invitation est un lien dynamique avec une valeur de paramètre de link qui indique qu'il provient de votre utilisateur existant.

Il existe de nombreuses façons de formater ces charges utiles de paramètres de link et de les lier à votre application. Un moyen simple consiste à spécifier l'ID de compte utilisateur de l'expéditeur dans un paramètre de requête comme dans l'exemple suivant:

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

Ensuite, pour créer des liens dynamiques pouvant être inclus dans une invitation, vous pouvez utiliser 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
}

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

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

Envoyez les invitations

Maintenant que vous avez créé le lien, vous pouvez l'inclure dans une invitation. L'invitation peut être un e-mail, un SMS ou tout autre support, en fonction de ce qui est le plus approprié pour votre application et votre public.

Par exemple, pour envoyer une invitation par e-mail:

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)

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

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

Récupérez les informations de référence dans votre application

Lorsque le destinataire de l'invitation ouvre le lien de parrainage, il sera dirigé vers l'App Store ou le Play Store pour installer votre application si elle n'est pas déjà installée. Ensuite, lorsqu'ils ouvrent votre application pour la première fois, vous pouvez récupérer les informations de parrainage que vous avez incluses dans le lien dynamique et les utiliser pour appliquer la récompense.

Habituellement, vous souhaitez accorder des récompenses de parrainage uniquement après l'inscription du destinataire de l'invitation, ou même seulement après que le nouvel utilisateur a terminé une tâche. Tant que les critères de récompense ne sont pas remplis, vous devez garder une trace des informations de récompense que vous avez obtenues du lien dynamique.

Une façon de garder une trace de ces informations est de connecter l'utilisateur de manière anonyme et de stocker les données dans l'enregistrement de la base de données en temps réel du compte anonyme. Lorsque le destinataire s'inscrit et que le compte anonyme est converti en compte permanent, le nouveau compte aura le même UID que le compte anonyme et, par conséquent, aura accès aux informations de récompense.

Par exemple, pour enregistrer l'UID du référent une fois que le destinataire a ouvert votre application:

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
}

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

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

Ensuite, lorsque le destinataire de l'invitation décide de créer un compte, vous pouvez transférer les informations de référence du compte anonyme vers le nouveau compte du destinataire de l'invitation.

Tout d'abord, obtenez un objet AuthCredential à l'aide de la méthode de connexion que l'invité souhaite utiliser. Par exemple, pour vous connecter avec une adresse e-mail et un mot de passe:

iOS (Swift)

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

Java

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

Kotlin + KTX

val credential = EmailAuthProvider.getCredential(email, password)

Ensuite, liez ces informations d'identification au compte anonyme:

iOS (Swift)

if let user = Auth.auth().currentUser {
  user.link(with: credential) { (user, error) in
    // 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.
            }
        });

Kotlin + KTX

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

Le nouveau compte permanent a accès à toutes les données de récompense que vous avez ajoutées au compte anonyme.

Accorder des récompenses au parrain et au destinataire

Maintenant que vous avez récupéré et enregistré les données d'invitation à partir du lien dynamique, vous pouvez accorder les récompenses de parrainage au référent et au destinataire chaque fois que les critères que vous souhaitez exiger sont remplis.

Bien que vous puissiez écrire dans la base de données en temps réel à partir de votre application cliente, vous souhaiterez souvent autoriser uniquement l'accès en lecture aux données telles que la devise de l'application depuis vos applications et effectuer des opérations d'écriture uniquement à partir de votre backend. Ce backend peut être n'importe quel système capable d'exécuter le SDK Firebase Admin, mais il est souvent plus simple d'utiliser Cloud Functions pour effectuer ces tâches.

Par exemple, supposons que vous ayez un jeu et que vous souhaitiez accorder une récompense en monnaie du jeu au destinataire une fois que le destinataire s'est inscrit, et au parrain une fois que le destinataire a atteint le niveau 5.

Pour accorder la récompense pour l'inscription, déployez une fonction qui surveille la création d'une clé de base de données en temps réel spécifique et accorde la récompense lorsqu'elle l'est. Par example:

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

Ensuite, lorsqu'un nouvel utilisateur s'inscrit, déclenchez cette fonction en créant la clé Realtime Database. Par exemple, déclenchez la fonction dans l' linkWithCredential de succès de linkWithCredential , que vous avez créé à l'étape précédente:

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

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

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

Pour accorder une récompense au référent lorsque le destinataire atteint le niveau 5, déployez une fonction qui surveille les modifications du champ de level dans vos enregistrements utilisateur. Si un utilisateur est passé du niveau 4 au niveau 5 et que l'utilisateur a enregistré un référent, accordez la récompense:

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

Le parrain et votre nouvel utilisateur ont maintenant reçu leurs récompenses.