Save the date - Google I/O returns May 18-20. Register to get the most out of the digital experience: Build your schedule, reserve space, participate in Q&As, earn Google Developer profile badges, and more. Register now
Ta strona została przetłumaczona przez Cloud Translation API.
Switch to English

Nagradzaj polecenia

Jednym z najskuteczniejszych sposobów pozyskiwania nowych użytkowników są polecenia użytkowników. Możesz używać linków dynamicznych wraz z bazą danych czasu rzeczywistego i funkcjami chmury dla Firebase, aby zachęcić użytkowników do zapraszania znajomych, oferując nagrody w aplikacji za udane skierowania zarówno do osoby polecającej, jak i do odbiorcy.

Kluczowe korzyści

  • Przyspiesz rozwój, zachęcając użytkowników do zapraszania znajomych.
  • Linki zaproszeń działają na różnych platformach.
  • Nowi użytkownicy otwierający Twoją aplikację po raz pierwszy otrzymują pierwsze uruchomienie, które dostosujesz do swoich potrzeb. Na przykład możesz automatycznie połączyć ich ze znajomym, który ich zaprosił.
  • Opcjonalnie opóźnij przyznawanie nagród, dopóki nowi użytkownicy nie ukończą jakiegoś zadania wprowadzającego, takiego jak ukończenie samouczka.

Oto jak zacząć!

Skonfiguruj Firebase i pakiet Dynamic Links SDK

Skonfiguruj nowy projekt Firebase i zainstaluj pakiet SDK Dynamic Links w swojej aplikacji. ( iOS , Android , C ++ , Unity ). Zainstalowanie pakietu SDK Dynamic Links umożliwia Firebase przekazywanie danych o Dynamic Link do aplikacji, w tym po zainstalowaniu aplikacji przez użytkownika. Bez pakietu SDK nie ma możliwości połączenia użytkownika po instalacji za pomocą kliknięcia przed instalacją.

Aby utworzyć zaproszenie, najpierw utwórz łącze, które odbiorca otwiera w celu zaakceptowania zaproszenia. Później umieścisz ten link w tekście zaproszenia. Gdy odbiorca zaproszenia zainstaluje Twoją aplikację, otwierając łącze, może uzyskać spersonalizowane pierwsze uruchomienie, w tym nagrodę w aplikacji.

To łącze z zaproszeniem jest łączem dynamicznym z wartością parametru link , która wskazuje, że pochodzi od istniejącego użytkownika.

Istnieje wiele sposobów formatowania tych ładunków parametrów link i powiązania ich z aplikacją. Prostym sposobem jest określenie identyfikatora konta użytkownika nadawcy w parametrze zapytania, jak w poniższym przykładzie:

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

Następnie, aby utworzyć linki dynamiczne nadające się do umieszczenia w zaproszeniu, możesz użyć interfejsu Dynamic Link Builder API:

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
}

Jawa

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

Wyślij zaproszenia

Po utworzeniu łącza możesz dołączyć go do zaproszenia. Zaproszenie może być e-mailem, wiadomością SMS lub innym medium, w zależności od tego, co jest najbardziej odpowiednie dla Twojej aplikacji i odbiorców.

Na przykład, aby wysłać zaproszenie 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)

Jawa

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

Pobierz informacje o skierowaniach w swojej aplikacji

Gdy odbiorca zaproszenia otworzy link polecający, zostanie przekierowany do App Store lub Play Store w celu zainstalowania aplikacji, jeśli nie jest jeszcze zainstalowana. Następnie, kiedy otworzą Twoją aplikację po raz pierwszy, możesz pobrać informacje o poleceniu, które umieściłeś w linku dynamicznym i użyć ich, aby zastosować nagrodę.

Zwykle chcesz przyznać nagrody za polecenie dopiero po zarejestrowaniu się odbiorcy zaproszenia lub dopiero po wykonaniu przez nowego użytkownika jakiegoś zadania. Dopóki kryteria nagrody nie zostaną spełnione, musisz śledzić informacje o nagrodach, które otrzymałeś z linku dynamicznego.

Jednym ze sposobów śledzenia tych informacji jest anonimowe logowanie użytkownika i przechowywanie danych w rekordzie bazy danych czasu rzeczywistego anonimowego konta. Kiedy odbiorca zarejestruje się, a anonimowe konto zostanie przekształcone w konto stałe, nowe konto będzie miało ten sam UID, co konto anonimowe, dzięki czemu będzie miało dostęp do informacji o nagrodzie.

Na przykład, aby zapisać identyfikator UID strony odsyłającej po otwarciu aplikacji przez odbiorcę:

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
}

Jawa

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

Następnie, gdy odbiorca zaproszenia zdecyduje się utworzyć konto, możesz przenieść informacje o skierowaniu z anonimowego konta na nowe konto odbiorcy zaproszenia.

Najpierw AuthCredential obiekt AuthCredential przy użyciu metody logowania, której chce użyć zaproszona osoba. Na przykład, aby zalogować się za pomocą adresu e-mail i hasła:

iOS (Swift)

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

Jawa

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

Kotlin + KTX

val credential = EmailAuthProvider.getCredential(email, password)

Następnie połącz to poświadczenie z anonimowym kontem:

iOS (Swift)

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

Jawa

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

Nowe, stałe konto ma dostęp do wszystkich danych nagród, które dodałeś do anonimowego konta.

Przyznaj nagrody polecającemu i odbiorcy

Po pobraniu i zapisaniu danych zaproszenia z linku dynamicznego możesz przyznać nagrody za polecenie osobie polecającej i odbiorcy, gdy tylko zostaną spełnione wymagane kryteria.

Chociaż możesz pisać do bazy danych czasu rzeczywistego z aplikacji klienckiej, często będziesz chciał zezwolić tylko na dostęp do odczytu danych, takich jak waluta w aplikacji, z aplikacji i wykonywać operacje zapisu tylko z zaplecza. Takim zapleczem może być dowolny system, na którym można uruchomić pakiet Firebase Admin SDK, ale często do wykonywania tych zadań najłatwiej jest użyć funkcji Cloud Functions.

Na przykład załóżmy, że masz grę i chcesz przyznać nagrodę w postaci waluty w grze odbiorcy po tym, jak się zarejestruje, a polecającemu, gdy odbiorca osiągnie poziom 5.

Aby przyznać nagrodę za rejestrację, należy wdrożyć funkcję, która obserwuje określony klucz bazy danych czasu rzeczywistego, który ma zostać utworzony, i przyznaje nagrodę, gdy jest. Na przykład:

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

Następnie, gdy zarejestruje się nowy użytkownik, uruchom tę funkcję, tworząc klucz bazy danych czasu rzeczywistego. Na przykład linkWithCredential funkcję w linkWithCredential sukcesu linkWithCredential , który został utworzony w poprzednim kroku:

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

Jawa

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

Aby przyznać nagrodę osobie polecającej, gdy odbiorca osiągnie poziom 5, zastosuj funkcję, która śledzi zmiany w polu level w Twoich rekordach użytkowników. Jeśli użytkownik przeszedł z poziomu 4 na poziom 5, a użytkownik ma zarejestrowaną osobę polecającą, przyznaj nagrodę:

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

Zarówno osoba polecająca, jak i nowy użytkownik otrzymali teraz swoje nagrody.