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

Zdobądź nowych użytkowników, nagradzając rekomendacje użytkowników

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

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

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, którzy otwierają Twoją aplikację po raz pierwszy, otrzymują dostosowane do nich środowisko pierwszego uruchomienia. 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 wykonają 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 Dynamic Links SDK umożliwia Firebase przekazywanie danych o łączu dynamicznym do aplikacji, także 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 otwierane przez odbiorcę w celu zaakceptowania zaproszenia. Później umieścisz ten link w treści 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 sformatowania tych ładunków parametrów link i powiązania ich z aplikacją. Prostym sposobem jest podanie identyfikatora konta użytkownika nadawcy w parametrze zapytania, tak jak w poniższym przykładzie:

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

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

Szybki

Uwaga: ten produkt Firebase nie jest dostępny w systemach docelowych macOS, Mac Catalyst, tvOS ani 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();
                // ...
            }
        });

Wyślij zaproszenia

Po utworzeniu łącza możesz dołączyć je do zaproszenia. Zaproszeniem może być e-mail, SMS lub inny nośnik, 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:

Szybki

Uwaga: ten produkt Firebase nie jest dostępny w systemach docelowych macOS, Mac Catalyst, tvOS ani 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);
}

Pobierz informacje o skierowaniu w swojej aplikacji

Gdy odbiorca zaproszenia otworzy łącze polecające, zostanie przekierowany do sklepu 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 rekomendacji, które umieściłeś w łączu dynamicznym, i użyć ich do zastosowania nagrody.

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

Jednym ze sposobów śledzenia tych informacji jest anonimowe logowanie użytkownika i przechowywanie danych w rekordzie Bazy danych czasu rzeczywistego konta anonimowego. Gdy odbiorca zarejestruje się, a konto anonimowe 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 tym, jak odbiorca otworzy Twoją aplikację:

Szybki

Uwaga: ten produkt Firebase nie jest dostępny w systemach docelowych macOS, Mac Catalyst, tvOS ani 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);
                }
            });
}

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

Najpierw pobierz 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:

Szybki

Uwaga: ten produkt Firebase nie jest dostępny w systemach docelowych macOS, Mac Catalyst, tvOS ani watchOS.
let credential = EmailAuthProvider.credential(withEmail: email, password: password)

Kotlin+KTX

val credential = EmailAuthProvider.getCredential(email, password)

Java

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

Następnie połącz te dane uwierzytelniające z kontem anonimowym:

Szybki

Uwaga: ten produkt Firebase nie jest dostępny w systemach docelowych macOS, Mac Catalyst, tvOS ani 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.
            }
        });

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

Przyznaj nagrody polecającemu i odbiorcy

Teraz, po pobraniu i zapisaniu danych zaproszenia z łącza dynamicznego, możesz przyznać nagrody za rekomendację osobie polecającej i odbiorcy za każdym razem, gdy zostaną spełnione wymagane kryteria.

Chociaż możesz zapisywać w bazie danych czasu rzeczywistego z poziomu 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 z zaplecza. Takim zapleczem może być dowolny system obsługujący pakiet Firebase Admin SDK, ale do wykonywania 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 zarejestrowaniu się odbiorcy oraz osobie polecającej, gdy odbiorca osiągnie poziom 5.

Aby przyznać nagrodę za rejestrację, wdróż funkcję, która obserwuje tworzenie określonego klucza bazy danych czasu rzeczywistego i przyznaje nagrodę, gdy to nastąpi. 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 uruchom funkcję w odbiorniku sukcesu linkWithCredential , który utworzyłeś w poprzednim kroku:

Szybki

Uwaga: ten produkt Firebase nie jest dostępny w systemach docelowych macOS, Mac Catalyst, tvOS ani 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);
            }
        });

Aby przyznać nagrodę osobie polecającej, gdy odbiorca osiągnie poziom 5, wdróż funkcję, która obserwuje zmiany w polu level w rekordach użytkownika. Jeśli użytkownik przeszedł z poziomu 4 na poziom 5 i ma zarejestrowanego polecającego, 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 Twój nowy użytkownik otrzymali już swoje nagrody.