אם משתמשים בממשקי API של FCM כדי ליצור בקשות שליחה באופן פרוגרמטי, אפשר לגלות שבמשך זמן אתם מבזבזים משאבים על ידי שליחת הודעות מכשירים עם אסימוני רישום לא פעילים. המצב הזה יכול להשפיע על נתוני העברת ההודעות שמדווחים במסוף Firebase או על נתונים שיוצאו ל-BigQuery, ויוצג כתוצאה מכך ירידה דרמטית (אבל לא תקפה בפועל) בשיעורי ההעברה. הזה במדריך הזה מתוארות כמה מהצעדים שתוכלו לנקוט כדי להבטיח שהמסר יהיה יעיל טירגוט ודיווח תקין על הצגת מודעות.
אסימוני רישום לא פעילים או שהתוקף שלהם פג
אסימוני רישום לא פעילים הם אסימונים שמשויכים למכשירים לא פעילים עם לא מחובר ל-FCM במשך יותר מחודש. ככל שעובר הזמן, הסיכוי שהמכשיר יתחבר שוב ל-FCM הולך ופוחת. ההודעה סביר להניח שלא יהיו שליחת הודעות אימייל והפצת נושאי לכולם עבור האסימונים המיושנים האלה. נמסר.
יש כמה סיבות לכך שאסימון יכול להפוך למיושן. לדוגמה, המכשיר שהאסימון משויך אליו עלולים לאבד, להשמיד או לשמור אותו, נשכח.
כשיהיו לטוקנים לא תקפים 270 ימים של חוסר פעילות, FCM יתייחס אליהם בתור אסימונים שפג תוקפם. אחרי שהתוקף של אסימון פג, FCM מסמן אותו כלא חוקי ו דוחה הודעות לשם. עם זאת, FCM מנפיק אסימון חדש עבור האפליקציה במקרה הנדיר שהמכשיר מתחבר שוב והאפליקציה נפתחת.
שיטות מומלצות בסיסיות
יש כמה שיטות בסיסיות שכדאי לפעול לפיהן בכל אפליקציה שבה משתמשים ממשקי API של FCM לבניית בקשות שליחה באופן פרוגרמטי. המשחק העיקרי הטוב ביותר הן:
- אחזור אסימוני רישום מ-FCM ושמירתם בשרת תפקיד חשוב עבור השרת הוא לעקוב אחר הביצועים של כל לקוח ולשמור רשימה מעודכנת של האסימונים הפעילים. מומלץ מאוד להטמיע חותמת זמן של אסימון בקוד ובשרתים שלך, ולעדכן את במרווחי זמן קבועים.
- שומרים על עדכניות האסימון ומסירים אסימונים לא פעילים. בנוסף להסרת אסימונים ש-FCM כבר לא מחשיב כתקינים, כדאי לעקוב אחרי סימנים אחרים לכך שהאסימונים לא תקפים יותר ולהסיר אותם באופן יזום. המדריך הזה מתואר בחלק מהאפשרויות העומדות לרשותכם לצורך כך.
אחזור ואחסון של אסימוני רישום
בזמן ההפעלה הראשונית של האפליקציה, ה-SDK של FCM יוצר רישום אסימון למופע של אפליקציית הלקוח. זהו האסימון שצריך לכלול בבקשות שליחה ממוקדות מה-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 נחשב ללא פעיל אם האפליקציה שלו המכונה לא מחוברת כבר חודש. סביר להניח שכל אסימון מלפני יותר מחודש להיות מכשיר לא פעיל, אחרת, מכשיר פעיל היה מרענן את ב-Assistant.
בהתאם לתרחיש לדוגמה שלכם, חודש אחד יכול להיות קצר או ארוך מדי, לכן כדי לקבוע מהם הקריטריונים שמתאימים לכם.
זיהוי תגובות לא חוקיות של אסימונים מהקצה העורפי של FCM
צריך לזהות תגובות לא תקינות לאסימונים של FCM ולהגיב באמצעות למחוק מהמערכת את כל אסימוני הרישום שידוע שהם לא חוקיים או שהתוקף שלהם פג. ב-HTTP v1 API, הודעות השגיאה האלה עשויות לציין אסימונים לא חוקיים או שהתוקף שלהם פג לבקשת השליחה שלך:
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):
לפלטפורמות של ApplegetToken()
ל-Android) ולאחר מכן לשלוח את האסימון הנוכחי לשרת של האפליקציה לאחסון (עם חותמת זמן). זו יכולה להיות משימה חודשית שמוגדרת לכיסוי כל לקוחות או אסימונים. - מוסיפים לוגיקה לשרת כדי לעדכן את חותמת הזמן של האסימון במרווחי זמן קבועים, ללא קשר לשינוי באסימון.
דוגמה ללוגיקה של Android לעדכון אסימונים באמצעות WorkManager, לראות ניהול אסימוני העברת הודעות בענן בבלוג של Firebase.
לא משנה באיזו תבנית תזמון פועלת, חשוב לעדכן את האסימונים מדי פעם. תדירות העדכון של פעם בחודש יוצרת איזון טוב בין השפעת הסוללה וזיהוי של אסימוני רישום לא פעילים. הרענון הזה מאפשר גם להבטיח שכל מכשיר שלא יהיה פעיל ירענן את הרישום שלו כאשר הופך להיות פעיל שוב. אין יתרון בביצוע רענון בתדירות גבוהה יותר מאשר בכל שבוע.
הסרת טוקני רישום לא תקינים
לפני שליחת הודעות למכשיר, חשוב לוודא שחותמת הזמן של אסימון הרישום של המכשיר נמצאת בחלון הזמן של סטטוס הלא עדכני. לדוגמה,
יכול לבצע את ההטמעה Cloud Functions for 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(); });
});
ביטול הרשמה של אסימונים לא תקינים לנושאים
אם משתמשים בנושאים, כדאי גם לבטל את הרישום של אסימונים לא פעילים מהנושאים שאליהם הם מנויים. כדי לעשות זאת:
- האפליקציה שלכם אמורה להירשם מחדש לנושאים פעם בחודש, ובכל פעם שינויים באסימון הרישום. כך נוצר פתרון לתיקון עצמי, שבו המינויים מופיעים מחדש באופן אוטומטי כשאפליקציה הופכת שוב לפעילה.
- אם מופע של אפליקציה לא פעיל במשך חודש אחד (או חלון הזמן הלא פעיל שלכם), אתם צריך לבטל את ההרשמה לנושאים באמצעות Firebase Admin SDK אל למחוק את האסימון למיפוי הנושא מהקצה העורפי FCM.
היתרון של שני השלבים האלה הוא שהמעריצים שלך יתרחשו מהר יותר, יהיו פחות אסימונים לא פעילים שאפשר להשתמש בהם, ומופעי האפליקציה הלא פעילים שלכם להירשם מחדש באופן אוטומטי כשהם יהיו פעילים שוב.
מדידת הצלחת ההעברה
כדי לקבל תמונה מדויקת ככל האפשר של העברת ההודעות, מומלץ לשלוח הודעות רק למכונות של האפליקציה שבהן נעשה שימוש פעיל. חשוב במיוחד לעשות זאת אם אתם שולחים הודעות באופן קבוע בנושאים עם מספר גדול של מנויים. אם חלק מהמנויים האלה לא פעילים בפועל, ההשפעה על נתוני ההעברה עשויה להיות משמעותית לאורך זמן.
לפני שמטרגטים הודעות לאסימון, כדאי להביא בחשבון את הדברים הבאים:
- ביצוע האימות ב-Google Analytics, נתונים שתועדו ב-BigQuery או אותות מעקב אחרים לציין שהאסימון פעיל.
- האם ניסיונות קודמים של מסירה נכשלו באופן עקבי במשך פרק זמן מסוים?
- האם אסימון הרישום עודכן בשרתים שלך בחודש האחרון?
- במכשירי Android, צריך להשתמש ב-FCM Data API
לדווח על אחוז גבוה של כשלים בשליחת ההודעות עקב
droppedDeviceInactive
?
מידע נוסף על העברה זמין במאמר הסבר על העברת הודעות.