שיטות עבודה מומלצות לניהול אסימוני רישום של FCM

אם אתה משתמש בממשקי API של FCM כדי לבנות בקשות שליחה באופן פרוגרמטי, אתה עלול לגלות שלאורך זמן אתה מבזבז משאבים על ידי שליחת הודעות למכשירים לא פעילים עם אסימוני רישום מיושנים. מצב זה יכול להשפיע על נתוני מסירת ההודעות המדווחים במסוף Firebase או על הנתונים המיוצאים ל-BigQuery, ולהופיע כירידה דרמטית (אך לא תקפה בפועל) בשיעורי המסירה. מדריך זה דן בכמה אמצעים שתוכל לנקוט כדי להבטיח מיקוד יעיל של מסרים ודיווח מסירה חוקי.

אסימוני רישום מיושנים ופג תוקפם

אסימוני רישום מיושנים הם אסימונים המשויכים למכשירים לא פעילים שלא התחברו ל-FCM במשך יותר מחודש. ככל שחולף הזמן, הסיכוי שהמכשיר יתחבר שוב ל-FCM הולך ופוחת. לא סביר שיימסרו אי פעם שליחה של הודעות והתעניינות בנושאים עבור האסימונים המעופשים האלה.

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

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

שיטות עבודה מומלצות בסיסיות

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

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

אחזר ואחסן אסימוני רישום

עם ההפעלה הראשונית של האפליקציה שלך, FCM SDK מייצר אסימון רישום עבור מופע אפליקציית הלקוח. זהו האסימון שעליך לכלול בבקשות שליחה ממוקדות מהממשק ה-API, או להוסיף למנויים לנושאים לצורך מיקוד לנושאים.

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

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

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

דוגמה: אחסן אסימונים וחותמות זמן ב-Cloud Firestore

לדוגמה, אתה יכול להשתמש ב-Cloud Firestore כדי לאחסן אסימונים באוסף שנקרא fcmTokens . כל מזהה מסמך באוסף מתאים לזיהוי משתמש, והמסמך מאחסן את אסימון הרישום הנוכחי ואת חותמת הזמן המעודכנת האחרונה שלו. השתמש בפונקציית set כפי שמוצגת בדוגמה זו של Kotlin:

    /**
     * Persist token to third-party servers.
     *
     * Modify this method to associate the user's FCM registration token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private fun sendTokenToServer(token: String?) {
        // If you're running your own server, call API to send token and today's date for the user

        // Example shown below with Firestore
        // Add token and timestamp to Firestore for this user
        val deviceToken = hashMapOf(
            "token" to token,
            "timestamp" to FieldValue.serverTimestamp(),
        )
        // Get user ID from Firebase Auth or your own server
        Firebase.firestore.collection("fcmTokens").document("myuserid")
            .set(deviceToken)
    }

בכל פעם שאסימון מאוחזר, הוא מאוחסן ב-Cloud Firestore על ידי קריאת sendTokenToServer :

    /**
     * Called if the FCM registration token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the
     * FCM registration token is initially generated so this is where you would retrieve the token.
     */
    override fun onNewToken(token: String) {
        Log.d(TAG, "Refreshed token: $token")

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        // FCM registration token to your app server.
        sendTokenToServer(token)
    }
        var token = Firebase.messaging.token.await()

        // Check whether the retrieved token matches the one on your server for this user's device
        val preferences = this.getPreferences(Context.MODE_PRIVATE)
        val tokenStored = preferences.getString("deviceToken", "")
        lifecycleScope.launch {
            if (tokenStored == "" || tokenStored != token)
            {
                // If you have your own server, call API to send the above token and Date() for this user's device

                // Example shown below with Firestore
                // Add token and timestamp to Firestore for this user
                val deviceToken = hashMapOf(
                    "token" to token,
                    "timestamp" to FieldValue.serverTimestamp(),
                )

                // Get user ID from Firebase Auth or your own server
                Firebase.firestore.collection("fcmTokens").document("myuserid")
                    .set(deviceToken).await()
            }
        }

שמור על טריות האסימון והסר אסימונים מיושנים

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

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

זיהוי תגובות אסימון לא חוקיות מה-backend של FCM

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

  • UNREGISTERED (HTTP 404)
  • INVALID_ARGUMENT (HTTP 400)

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

    // Registration token comes from the client FCM SDKs
    const registrationToken = 'YOUR_REGISTRATION_TOKEN';

    const message = {
    data: {
        // Information you want to send inside of notification
    },
    token: registrationToken
    };

    // Send message to device with provided registration token
    getMessaging().send(message)
    .then((response) => {
        // Response is a message ID string.
    })
    .catch((error) => {
        // Delete token for user if error code is UNREGISTERED or INVALID_ARGUMENT.
        if (errorCode == "messaging/registration-token-not-registered") {
            // If you're running your own server, call API to delete the
            token for the user

            // Example shown below with Firestore
            // Get user ID from Firebase Auth or your own server
            Firebase.firestore.collection("fcmTokens").document(user.uid).delete()
        }
    });

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

עדכן אסימונים על בסיס קבוע

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

  • הוסף לוגיקת אפליקציה באפליקציית הלקוח שלך כדי לאחזר את האסימון הנוכחי באמצעות קריאת ה-API המתאימה (כגון token(completion): עבור פלטפורמות אפל או getToken() עבור אנדרואיד) ולאחר מכן שלח את האסימון הנוכחי לשרת האפליקציה שלך לאחסון (עם חותמת זמן). זו יכולה להיות עבודה חודשית המוגדרת לכסות את כל הלקוחות או האסימונים.
  • הוסף לוגיקת שרת כדי לעדכן את חותמת הזמן של האסימון במרווחי זמן קבועים, ללא קשר לשאלה אם האסימון השתנה או לא.

לדוגמא של לוגיקה של אנדרואיד לעדכון אסימונים באמצעות WorkManager , ראה ניהול אסימוני הודעות בענן בבלוג Firebase.

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

הסר אסימוני רישום מיושנים

לפני שליחת הודעות למכשיר, ודא שחותמת הזמן של אסימון הרישום של המכשיר נמצאת בתקופת חלון העיפרון שלך. לדוגמה, תוכל ליישם את Cloud Functions עבור Firebase כדי להריץ בדיקה יומית כדי לוודא שחותמת הזמן נמצאת בתוך תקופת חלון עיפון מוגדרת כגון const EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30; ולאחר מכן הסר אסימונים מיושנים:

exports.pruneTokens = functions.pubsub.schedule('every 24 hours').onRun(async (context) => {
  // Get all documents where the timestamp exceeds is not within the past month
  const staleTokensResult = await admin.firestore().collection('fcmTokens')
      .where("timestamp", "<", Date.now() - EXPIRATION_TIME)
      .get();
  // Delete devices with stale tokens
  staleTokensResult.forEach(function(doc) { doc.ref.delete(); });
});

בטל את הרישום של אסימונים מיושנים לנושאים

אם אתה משתמש בנושאים, ייתכן שתרצה גם לבטל את הרישום של אסימונים מיושנים מהנושאים אליהם הם רשומים. זה כולל שני שלבים:

  1. האפליקציה שלך צריכה להירשם מחדש לנושאים פעם בחודש ובכל פעם שאסימון הרישום משתנה. זה יוצר פתרון לריפוי עצמי, שבו המנויים מופיעים מחדש באופן אוטומטי כאשר אפליקציה חוזרת להיות פעילה.
  2. אם מופע של אפליקציה לא פעיל למשך חודש אחד (או חלון העיפון שלך) עליך לבטל את הרישום שלו לנושאים באמצעות Firebase Admin SDK כדי למחוק את מיפוי האסימון לנושא מה-backend של FCM.

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

למדוד את הצלחת המסירה

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

לפני מיקוד הודעות לאסימון, שקול:

  • האם Google Analytics, נתונים שנלכדו ב-BigQuery או אותות מעקב אחרים מצביעים על כך שהאסימון פעיל?
  • האם ניסיונות מסירה קודמים נכשלו באופן עקבי לאורך תקופה מסוימת?
  • האם אסימון הרישום עודכן בשרתים שלך בחודש האחרון?
  • עבור מכשירי אנדרואיד, האם ממשק ה- API של FCM Data מדווח על אחוז גבוה של כשלים בהעברת הודעות עקב droppedDeviceInactive ?

למידע נוסף על מסירה, ראה הבנת מסירת הודעות .