הפניות לתגמול

אחת הדרכים היעילות ביותר להשיג משתמשים חדשים היא באמצעות הפניות למשתמשים. אתה יכול להשתמש דינמי קישורים יחד עם מסד נתונים בזמן אמת לבין פונקציות ענן עבור Firebase כדי לעודד את המשתמשים שלך כדי להזמין את החברים שלהם על ידי מתן תגמולים ב-אפליקציה עבור הפניות מוצלחות הוא המפנה ואת המקבל.

יתרונות מרכזיים

  • האץ את הצמיחה על ידי מתן תמריץ למשתמשים שלך להזמין את חבריהם.
  • קישורי הזמנה עובדים על פני פלטפורמות.
  • משתמשים חדשים הפותחים את האפליקציה שלך בפעם הראשונה מקבלים חווית הפעלה ראשונה שתתאים אישית עבורם. לדוגמה, תוכל לחבר אותם אוטומטית עם החבר שהזמין אותם.
  • לחלופין, דחה את מתן הפרסים עד שמשתמשים חדשים יסיימו משימת היכרות כלשהן, כגון השלמת הדרכה.

הנה איך להתחיל!

הגדר את Firebase ואת ה- SDK של קישורים דינאמיים

הגדר פרויקט Firebase חדש והתקן את ה- SDK של קישורים דינאמיים באפליקציה שלך. ( IOS , Android , C ++ , אחדות ). התקנת ה- SDK Dynamic Links מאפשרת ל- Firebase להעביר נתונים אודות הקישור הדינמי לאפליקציה, כולל לאחר שהמשתמש מתקין את האפליקציה. ללא ה- SDK, אין דרך לחבר משתמש לאחר התקנה בלחיצה מראש להתקנה.

כדי ליצור הזמנה, תחילה צור את הקישור שהנמען פותח כדי לקבל את ההזמנה. מאוחר יותר, תכלול קישור זה בטקסט ההזמנה. כאשר מקבל ההזמנה מתקין את האפליקציה שלך על ידי פתיחת הקישור, הוא יכול לקבל חוויה מותאמת אישית של ההפעלה הראשונה, כולל קבלת פרס בתוך האפליקציה.

הקישור של הזמנה זו הינה קישור דינמי עם link פרמטר ערך המציינת שהוא ממשתמש הקיים שלך.

ישנן דרכים רבות בהן ניתן לעצב אלה link מטענים פרמטר ולקשור אותם לתוך האפליקציה. דרך אחת פשוטה היא לציין את מזהה חשבון משתמש של השולח פרמטר השאילתה כמו בדוגמה הבאה:

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

ואז, כדי ליצור דינמיים קישורים מתאימים להיכלל הזמנה, אתה יכול להשתמש ב- API בונה קישור דינאמי:

iOS (סוויפט)

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
}

ג'אווה

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

קוטלין+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
    // ...
}

שלח את ההזמנות

כעת, לאחר שיצרת את הקישור, תוכל לכלול אותו בהזמנה. ההזמנה יכולה להיות מייל, הודעת SMS או כל אמצעי אחר, בהתאם למה שהכי מתאים לאפליקציה ולקהל שלכם.

לדוגמה, כדי לשלוח הזמנה בדוא"ל:

iOS (סוויפט)

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)

ג'אווה

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

קוטלין+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)
}

אחזר את פרטי ההפניה באפליקציה שלך

כאשר מקבל ההזמנה יפתח את קישור ההפניה, הוא יופנה לחנות האפליקציות או לחנות Play כדי להתקין את האפליקציה שלך אם היא עדיין לא מותקנת. לאחר מכן, כאשר הם פותחים את האפליקציה שלך בפעם הראשונה, תוכל לאחזר את פרטי ההפניה שכללת בקישור הדינמי ולהשתמש בו כדי להחיל את הפרס.

בדרך כלל, אתה רוצה להעניק פרסי הפניה רק ​​לאחר שנמען ההזמנה נרשם, או אפילו רק לאחר שהמשתמש החדש מסיים משימה כלשהי. עד שיתקיימו קריטריוני התגמול, עליך לעקוב אחר פרטי התגמול שקיבלת מהקישור הדינמי.

אחת הדרכים לעקוב אחר מידע זה היא להיכנס למשתמש באופן אנונימי ולאחסן את הנתונים ברשומת מסד הנתונים בזמן אמת של החשבון האנונימי. כאשר הנמען נרשם והחשבון האנונימי יומר לחשבון קבוע, לחשבון החדש יהיה אותו UID כמו החשבון האנונימי, וכתוצאה מכך תהיה לו גישה למידע התגמול.

לדוגמה, כדי לשמור את ה- UID של המפנה לאחר שהנמען יפתח את האפליקציה שלך:

iOS (סוויפט)

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
}

ג'אווה

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

קוטלין+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)
            }
}

לאחר מכן, כאשר מקבל ההזמנה מחליט ליצור חשבון, תוכל להעביר את פרטי ההפניה מהחשבון האנונימי לחשבון החדש של מקבל ההזמנה.

ראשית, לקבל AuthCredential אובייקט באמצעות כניסת שיטת המוזמן רוצה להשתמש. לדוגמה, כדי להיכנס באמצעות כתובת דוא"ל וסיסמה:

iOS (סוויפט)

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

ג'אווה

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

קוטלין+KTX

val credential = EmailAuthProvider.getCredential(email, password)

לאחר מכן, קשר את האישור הזה לחשבון האנונימי:

iOS (סוויפט)

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

ג'אווה

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

קוטלין+KTX

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

לחשבון החדש, הקבוע, יש גישה לכל נתוני התגמול שהוספת לחשבון האנונימי.

הענק פרסים למפנה ולנמען

כעת לאחר ששמרת ושמרת את נתוני ההזמנה מהקישור הדינמי, תוכל להעניק את תגמולי ההפניה למפנה ולנמען בכל עת שהתקיימו הקריטריונים שברצונך לדרוש.

למרות שאתה יכול לכתוב למסד הנתונים בזמן אמת מאפליקציית הלקוח שלך, לעתים קרובות תרצה לאפשר גישה לקריאה לנתונים כמו מטבע בתוך האפליקציה בלבד מהאפליקציות שלך ולבצע פעולות כתיבה רק מהמשקוף האחורי שלך. תומך תומך זה יכול להיות כל מערכת המסוגלת להריץ את SDK Admin SDB, אך לרוב קל יותר להשתמש בפונקציות ענן לביצוע משימות אלה.

לדוגמה, נניח שיש לך משחק ואתה רוצה להעניק תגמול של מטבע בתוך המשחק לנמען לאחר שהנמען נרשם, ולמפנה לאחר שהנמען יגיע לרמה 5.

כדי להעניק את הפרס על ההרשמה, פרוס פונקציה השומרת על יצירת מפתח ספציפי של מסד נתונים בזמן אמת, ומעניקה את הפרס כאשר הוא קיים. לדוגמה:

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

לאחר מכן, כאשר משתמש חדש נרשם, הפעל פונקציה זו על ידי יצירת מפתח מסד הנתונים בזמן אמת. לדוגמה, להפעיל את הפונקציה ב linkWithCredential המאזין ההצלחה של, אשר שיצרת בשלב הקודם:

iOS (סוויפט)

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

ג'אווה

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

קוטלין+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)
        }

כדי להעניק פרס לגורם המפנה כאשר מגיע לנמען רמה 5, לפרוס פונקציה שעונים עבור שינויים level שדה הרישומים המשתמש שלך. אם משתמש עבר מרמה 4 לרמה 5, והמשתמש רשם מפנה, העניק את הפרס:

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

המפנה והמשתמש החדש שלך קיבלו כעת את הפרסים שלהם.