Catch up on everthing we announced at this year's Firebase Summit. Learn more

Polecenia nagrody

Jednym z najskuteczniejszych sposobów pozyskiwania nowych użytkowników są polecenia użytkowników. Można użyć dynamiczne linki wraz z Realtime Database i funkcji Chmura Firebase aby zachęcić użytkowników do zapraszać swoich znajomych, oferując nagrody w aplikacji dla skierowań do udanych zarówno polecający a odbiorcą.

Kluczowe korzyści

  • Przyspiesz rozwój, zachęcając użytkowników do zapraszania znajomych.
  • Linki z zaproszeniami działają na różnych platformach.
  • Nowi użytkownicy otwierający Twoją aplikację po raz pierwszy uzyskują dostęp do środowiska po pierwszym uruchomieniu, które dostosowujesz do nich. Na przykład możesz automatycznie połączyć je ze znajomym, który ich zaprosił.
  • Opcjonalnie opóźnij przyznawanie nagród, dopóki nowi użytkownicy nie wykonają jakiegoś zadania wprowadzającego, takiego jak ukończenie samouczka.

Oto jak zacząć!

Skonfiguruj Firebase i pakiet SDK Linków dynamicznych

Skonfiguruj nowy projekt Firebase i zainstaluj pakiet SDK Dynamic Links w swojej aplikacji. ( IOS , Android , C ++ , Unity ). Zainstalowanie pakietu SDK linków dynamicznych umożliwia Firebase przekazywanie do aplikacji danych dotyczących linku dynamicznego, także po zainstalowaniu aplikacji przez użytkownika. Bez 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 otworzy odbiorca, aby zaakceptować zaproszenie. Później umieścisz ten link w tekście zaproszenia. Gdy odbiorca zaproszenia zainstaluje Twoją aplikację, otwierając łącze, może uzyskać spersonalizowane środowisko pierwszego uruchomienia, w tym otrzymać nagrodę w aplikacji.

Ten link jest zaproszenie Dynamic Link z link parametru wartość wskazującą, że jest z istniejącego użytkownika.

Istnieje wiele sposobów można sformatować te link parametrów ładunków i związać je w swojej aplikacji. Jednym z prostszych sposobów jest określenie nadawcy identyfikatora konta użytkownika w parametrze zapytania jak w poniższym przykładzie:

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

Następnie, aby utworzyć dynamiczne linki nadaje się do włączenia do zaproszenia, można użyć API Dynamic Link Builder:

Szybki

Uwaga: Ten produkt nie jest dostępny Firebase na MacOS, Mac Catalyst, tvOS lub celów 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
}

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

Teraz, po utworzeniu linku, możesz dołączyć go do zaproszenia. Zaproszenie może być e-mailem, SMS-em lub dowolnym 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-mailem:

Szybki

Uwaga: Ten produkt nie jest dostępny Firebase na MacOS, Mac Catalyst, tvOS lub celów 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)

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 rekomendacjach w swojej aplikacji

Gdy odbiorca zaproszenia otworzy link polecający, zostanie przekierowany do App Store lub Play Store w celu zainstalowania Twojej aplikacji, jeśli nie jest jeszcze zainstalowana. Następnie, gdy po raz pierwszy otworzą Twoją aplikację, możesz pobrać informacje o skierowaniu zawarte w Linku dynamicznym i użyć ich do przyznania nagrody.

Zazwyczaj chcesz przyznawać nagrody za polecenie dopiero po zarejestrowaniu się odbiorcy zaproszenia lub nawet po wykonaniu przez nowego użytkownika jakiegoś zadania. Dopóki kryteria nagrody nie zostaną spełnione, musisz śledzić informacje o nagrodzie, które uzyskałeś z Dynamic Link.

Jednym ze sposobów śledzenia tych informacji jest anonimowe zalogowanie użytkownika i przechowywanie danych w rekordzie Bazy danych czasu rzeczywistego konta anonimowego. Gdy odbiorca zarejestruje się, a konto anonimowe zostanie przekonwertowane na konto stałe, nowe konto będzie miało ten sam UID co konto anonimowe, a w rezultacie będzie miało dostęp do informacji o nagrodzie.

Na przykład, aby zapisać UID strony odsyłającej po tym, jak odbiorca otworzy Twoją aplikację:

Szybki

Uwaga: Ten produkt nie jest dostępny Firebase na MacOS, Mac Catalyst, tvOS lub celów watchOS.
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 konta anonimowego na nowe konto odbiorcy zaproszenia.

Po pierwsze, uzyskać AuthCredential obiekt za pomocą logowania metody zaproszona chce korzystać. Na przykład, aby zalogować się za pomocą adresu e-mail i hasła:

Szybki

Uwaga: Ten produkt nie jest dostępny Firebase na MacOS, Mac Catalyst, tvOS lub celów watchOS.
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 te poświadczenia z anonimowym kontem:

Szybki

Uwaga: Ten produkt nie jest dostępny Firebase na MacOS, Mac Catalyst, tvOS lub celów watchOS.
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 konta anonimowego.

Przyznaj nagrody polecającemu i odbiorcy

Teraz, po pobraniu i zapisaniu danych zaproszenia z Dynamic Link, możesz przyznać nagrody za polecenie polecającemu i odbiorcy za każdym razem, gdy spełnione są kryteria, których chcesz wymagać.

Chociaż możesz zapisywać w Bazie danych czasu rzeczywistego z aplikacji klienckiej, często chcesz zezwolić tylko na dostęp do odczytu danych, takich jak waluta w aplikacji, z aplikacji i wykonywać operacje zapisu tylko ze swojego zaplecza. Takim backendem może być dowolny system, w którym można uruchomić pakiet Firebase Admin SDK, ale do wykonania tych zadań często najłatwiej jest użyć Cloud Functions.

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

Aby przyznać nagrodę za rejestrację, wdróż funkcję, która wyszukuje 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 nowy użytkownik zarejestruje się, uruchom tę funkcję, tworząc klucz Bazy danych czasu rzeczywistego. Na przykład wywołać funkcję w linkWithCredential „s sukces słuchacza, który został utworzony w poprzednim kroku:

Szybki

Uwaga: Ten produkt nie jest dostępny Firebase na MacOS, Mac Catalyst, tvOS lub celów 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())
    }
  }
}

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ę dla polecający gdy osiągnie poziom 5 biorcy, wdrożyć funkcję zegarki na zmiany w level pola w rekordach użytkowników. Jeśli użytkownik przeszedł z poziomu 4 na poziom 5 i 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.