| בחירת פלטפורמה: | iOS+ Android Web Flutter Unity C++ |
במדריך הזה מוסבר איך להתחיל להשתמש ב-Firebase Cloud Messaging באפליקציות לקוח ב-C++ כדי לשלוח הודעות בצורה מהימנה.
כדי לכתוב את אפליקציית הלקוח של Firebase Cloud Messaging בפלטפורמות שונות באמצעות C++, צריך להשתמש ב-API של Firebase Cloud Messaging. C++ SDK פועל בפלטפורמות Android ו-Apple, אבל צריך לבצע הגדרה נוספת לכל פלטפורמה. במאמר הסבר על Firebase ל-C++ מוסבר איך ה-SDK ל-C++ ל-iOS ול-Android פועל עם FCM.
הגדרת Firebase ו-FCM SDK
Android
אם עדיין לא עשיתם זאת, הוסיפו את Firebase לפרויקט C++.
בהוראות ההגדרה המקושרות, צריך לעיין בדרישות לגבי המכשיר והאפליקציה לשימוש ב-SDK Firebase C++, כולל ההמלצה להשתמש ב-CMake כדי ליצור את האפליקציה.
בקובץ
build.gradleברמת הפרויקט, צריך לכלול את מאגר ה-Maven של Google בקטעיםbuildscriptו-allprojects.
יוצרים אובייקט של אפליקציית Firebase ומעבירים את סביבת ה-JNI וה-Activity:
app = ::firebase::App::Create(::firebase::AppOptions(), jni_env, activity);
מגדירים מחלקה שמטמיעה את הממשק של
firebase::messaging::Listener.מאתחלים את FCM, מעבירים את האפליקציה ומאזין מובנה:
::firebase::messaging::Initialize(app, listener);
באפליקציות שמסתמכות על Google Play Services SDK, צריך לבדוק אם במכשיר יש קובץ APK תואם של Google Play Services לפני שניגשים לתכונות. מידע נוסף זמין במאמר בנושא בדיקת קובץ ה-APK של Google Play Services.
iOS+
- אם עדיין לא עשיתם זאת, מוסיפים את Firebase לפרויקט C++. לאחר מכן, כדי להגדיר את הפרויקט ל-FCM:
- בקובץ Podfile של הפרויקט, מוסיפים את התלות ב-FCM:
pod 'FirebaseMessaging'
- גוררים את מסגרות
firebase.frameworkו-firebase_messaging.frameworkלפרויקט Xcode מתוך Firebase C++ SDK.
- בקובץ Podfile של הפרויקט, מוסיפים את התלות ב-FCM:
מעלים את מפתח האימות של APNs ל-Firebase. אם עדיין אין לכם מפתח אימות של APNs, הקפידו ליצור מפתח כזה ב-Apple Developer Member Center.
-
במסוף Firebase, עוברים אל
הגדרות > כללי. ואז לוחצים על הכרטיסייה העברת הודעות בענן. - בקטע APNs authentication key (מפתח אימות של APNs) שמופיע בקטע iOS app configuration (הגדרת אפליקציה ל-iOS), לוחצים על Upload (העלאה) כדי להעלות את מפתח האימות של סביבת הפיתוח, את מפתח האימות של סביבת הייצור או את שניהם. צריך להוסיף לפחות אחד.
- מחפשים את המיקום שבו שמרתם את המפתח, בוחרים אותו ולוחצים על פתיחה. מוסיפים את מזהה המפתח (זמין ב-Apple Developer Member Center) ולוחצים על Upload.
-
במסוף Firebase, עוברים אל
מגדירים את פרויקט Xcode כדי להפעיל התראות:
- בוחרים את הפרויקט באזור הניווט.
- בוחרים את יעד הפרויקט מאזור העריכה.
באזור העריכה, לוחצים על הכרטיסייה כללי.
- גוללים אל Linked Frameworks and Libraries (מסגרות וספריות מקושרות) ולוחצים על הלחצן + כדי להוסיף מסגרות.
בחלון שמופיע, גוללים אל UserNotifications.framework, לוחצים על הרשומה ואז על Add.
ה-framework הזה מופיע רק ב-Xcode מגרסה 8 ואילך, והוא נדרש על ידי הספרייה הזו.
באזור העריכה, לוחצים על הכרטיסייה יכולות.
- מעבירים את המתג התראות למצב מופעל.
- גוללים אל מצבי רקע ומעבירים את המתג למצב מופעל.
- בקטע Background Modes (מצבי רקע), בוחרים באפשרות Remote notifications (התראות מרחוק).
יוצרים אובייקט Firebase App:
app = ::firebase::App::Create(::firebase::AppOptions());
מגדירים מחלקה שמטמיעה את הממשק של
firebase::messaging::Listener.מאתחלים את העברת ההודעות בענן ב-Firebase, מעבירים את האפליקציה ואת Listener שהוגדר:
::firebase::messaging::Initialize(app, listener);
גישה למזהה ההתקנה של Firebase
הפעלת הרשמה באמצעות מזהה התקנה של Firebase
כדי להפעיל את רישום מופע האפליקציה ב-FCM באמצעות מזהה ההתקנה (FID) ב-Firebase, צריך קודם להפעיל את מזהי ההתקנה בהגדרות של האפליקציה בפלטפורמות Android ו-Apple:
Android
מוסיפים את רכיב <meta-data> הבא בתוך רכיב <application> של AndroidManifest.xml:
<meta-data android:name="firebase_messaging_installation_id_enabled" android:value="true" />
Swift
מוסיפים את המפתח FirebaseMessagingInstallationIdEnabled אל Info.plist ומגדירים אותו לערך YES:
FirebaseMessagingInstallationIdEnabled = YES
הטמעה של ה-Listener של onRegistrationReceived
כשמאתחלים את הספרייה Firebase Cloud Messaging, היא רושמת את המופע של אפליקציית הלקוח כדי לקבל הודעות באמצעות מזהה ההתקנה של Firebase (FID). האפליקציה תקבל את ה-FID באמצעות פונקציית ה-callback OnRegistrationReceived, שצריך להגדיר בהטמעה של firebase::messaging::Listener:
class MyListener : public firebase::messaging::Listener { public: void OnRegistrationReceived(const char* installation_id) override { LogMessage("Received Firebase Installation ID: %s", installation_id); // TODO: Send the Firebase Installation ID (FID) to your app server to // target this device for messages. } };
אם רוצים לטרגט את המופע הספציפי של האפליקציה, צריך לשלוח את ה-FID לשרת האפליקציה ולאחסן אותו בשיטה המועדפת.
רישום ידני כשההפעלה האוטומטית מושבתת
אפשר גם להפעיל את הרישום באופן ידני באמצעות FCM בזמן הריצה באמצעות Register():
// Manually register with FCM firebase::Future<void> register_future = firebase::messaging::Register(); register_future.OnCompletion([](const firebase::Future<void>& future) { if (future.status() == firebase::kFutureStatusComplete && future.error() == 0) { // Note: The registered Firebase Installation ID is delivered to the // OnRegistrationReceived callback. LogMessage("Registered with FCM"); } });
גישה לטוקן הרישום FCM (יצא משימוש)
בזמן האתחול של ספריית Firebase Cloud Messaging, מתבצעת בקשה לטוקן רישום עבור מופע אפליקציית הלקוח. האפליקציה תקבל את האסימון באמצעות הקריאה החוזרת (callback) של OnTokenReceived, שצריכה להיות מוגדרת במחלקה שמטמיעה את firebase::messaging::Listener.
אם אתם רוצים לטרגט את המופע הספציפי הזה של האפליקציה, אתם צריכים גישה לאסימון הזה.
הערה לגבי מסירת הודעות ב-Android
כשהאפליקציה לא פועלת בכלל ומשתמש מקיש על התראה,
ההודעה לא מנותבת כברירת מחדל דרך הקריאות החוזרות המובנות של FCM. במקרה כזה, מטעני מטען של הודעות מתקבלים דרך Intentשמשמש להפעלת האפליקציה. כדי ש-FCM יעביר את ההודעות הנכנסות האלה לקריאה החוזרת של ספריית C++, צריך לבטל את השיטה onNewIntent בפעילות ולהעביר את Intent אל MessageForwardingService.
import com.google.firebase.messaging.MessageForwardingService; class MyActivity extends Activity { private static final String TAG = "MyActvity"; @Override protected void onNewIntent(Intent intent) { Log.d(TAG, "A message was sent to this app while it was in the background."); Intent message = new Intent(this, MessageForwardingService.class); message.setAction(MessageForwardingService.ACTION_REMOTE_INTENT); message.putExtras(intent); message.setData(intent.getData()); // For older versions of Firebase C++ SDK (< 7.1.0), use `startService`. // startService(message); MessageForwardingService.enqueueWork(this, message); } }
הודעות שמתקבלות בזמן שהאפליקציה פועלת ברקע, התוכן של שדה ההתראה שלהן משמש לאכלוס ההתראה במגש המערכת, אבל תוכן ההתראה הזה לא מועבר אל FCM. כלומר, הערך של Message::notification יהיה null.
בקצרה:
| מצב האפליקציה | התראה | נתונים | שניהם |
|---|---|---|---|
| חזית | OnMessageReceived |
OnMessageReceived |
OnMessageReceived |
| רקע | מגש המערכת | OnMessageReceived |
התראה: מגש המערכת נתונים: בתוספות של הכוונה. |
טיפול בהודעות מותאמות אישית ב-Android
כברירת מחדל, התראות שנשלחות לאפליקציה מועברות אל ::firebase::messaging::Listener::OnMessageReceived, אבל במקרים מסוימים יכול להיות שתרצו לשנות את פעולת ברירת המחדל. כדי לעשות את זה ב-Android, צריך לכתוב מחלקות מותאמות אישית שמרחיבות את com.google.firebase.messaging.cpp.ListenerService וגם לעדכן את AndroidManifest.xml של הפרויקט.
שינוי ListenerService methods
ListenerService היא מחלקת Java שמיירטת הודעות נכנסות שנשלחות לאפליקציה ומנתבת אותן לספריית C++. כשהאפליקציה פועלת בחזית (או כשהאפליקציה פועלת ברקע והיא מקבלת מטען ייעודי (payload) של נתונים בלבד), ההודעות יעברו דרך אחד מהקריאות החוזרות (callbacks) שסופקו במחלקה הזו. כדי להוסיף התנהגות מותאמת אישית לטיפול בהודעות, צריך להרחיב את FCMברירת המחדל של ListenerService:
import com.google.firebase.messaging.cpp.ListenerService; class MyListenerService extends ListenerService {
על ידי החלפת השיטה ListenerService.onMessageReceived, אפשר לבצע פעולות על סמך האובייקט RemoteMessage שהתקבל ולקבל את נתוני ההודעה:
@Override public void onMessageReceived(RemoteMessage message) { Log.d(TAG, "A message has been received."); // Do additional logic... super.onMessageReceived(message); }
יש גם כמה שיטות אחרות ב-ListenerService שמשתמשים בהן בתדירות נמוכה יותר.
אפשר גם לשנות את הערכים האלה. מידע נוסף זמין בהפניה אל FirebaseMessagingService.
@Override public void onDeletedMessages() { Log.d(TAG, "Messages have been deleted on the server."); // Do additional logic... super.onDeletedMessages(); } @Override public void onMessageSent(String messageId) { Log.d(TAG, "An outgoing message has been sent."); // Do additional logic... super.onMessageSent(messageId); } @Override public void onSendError(String messageId, Exception exception) { Log.d(TAG, "An outgoing message encountered an error."); // Do additional logic... super.onSendError(messageId, exception); }
עדכון של AndroidManifest.xml
אחרי שכותבים את המחלקות בהתאמה אישית, צריך לכלול אותן ב-AndroidManifest.xml כדי שהן ייכנסו לתוקף. חשוב לוודא שקובץ המניפסט כולל את כלי המיזוג על ידי הצהרה על המאפיין המתאים בתוך התג <manifest>, באופן הבא:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.firebase.messaging.cpp.samples" xmlns:tools="http://schemas.android.com/tools">
בארכיון firebase_messaging_cpp.aar יש קובץ AndroidManifest.xml שמצהיר על ברירת המחדל של ListenerService ב-FCM. המניפסט הזה בדרך כלל מתמזג עם המניפסט הספציפי לפרויקט, וכך ListenerService יכול לפעול. צריך להחליף את ListenerService בשירות המאזין בהתאמה אישית. כדי לעשות את זה, מסירים את ברירת המחדל של ListenerService ומוסיפים את השירות בהתאמה אישית. אפשר לעשות את זה באמצעות השורות הבאות בקובץ AndroidManifest.xml של הפרויקט:
<service android:name="com.google.firebase.messaging.cpp.ListenerService" tools:node="remove" />
<service android:name="com.google.firebase.messaging.cpp.samples.MyListenerService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/> </intent-filter> </service>
גרסאות חדשות של Firebase C++ SDK (מגרסה 7.1.0 ואילך) משתמשות ב-JobIntentService, וצריך לבצע שינויים נוספים בקובץ AndroidManifest.xml.
<service android:name="com.google.firebase.messaging.MessageForwardingService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="false" > </service>
מניעת הפעלה אוטומטית
FCM יוצר אסימון רישום לטירגוט של מופע אפליקציה.
כשנוצר אסימון, הספרייה מעלה את המזהה ואת נתוני ההגדרות ל-Firebase. אם רוצים לקבל הסכמה מפורשת לפני השימוש בטוקן, אפשר למנוע את יצירת הטוקן בזמן ההגדרה על ידי השבתת FCM (וב-Android, גם Analytics). כדי לעשות את זה, מוסיפים ערך של מטא-נתונים ל-Info.plist (ולא ל-GoogleService-Info.plist) בפלטפורמות של אפל, או ל-AndroidManifest.xml ב-Android:
Android
<?xml version="1.0" encoding="utf-8"?> <application> <meta-data android:name="firebase_messaging_auto_init_enabled" android:value="false" /> <meta-data android:name="firebase_analytics_collection_enabled" android:value="false" /> </application>
Swift
FirebaseMessagingAutoInitEnabled = NO
כדי להפעיל מחדש את FCM, אפשר לבצע קריאה בזמן ריצה:
::firebase::messaging::SetRegistrationOnInitEnabled(true);
אחרי שמגדירים את הערך הזה, הוא נשמר גם כשמפעילים מחדש את האפליקציה.
הודעות עם קישורי עומק ב-Android
FCM מאפשר לשלוח הודעות שמכילות קישור עומק לאפליקציה. כדי לקבל הודעות שמכילות קישור עומק, צריך להוסיף מסנן Intent חדש לפעילות שמטפלת בקישורי עומק באפליקציה. מסנן ה-Intent צריך לתפוס קישורי עומק של הדומיין. אם ההודעות שלכם לא מכילות קישור עומק, אין צורך בהגדרה הזו. בקובץ AndroidManifest.xml:
<intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:host="CHANGE_THIS_DOMAIN.example.com" android:scheme="http"/> <data android:host="CHANGE_THIS_DOMAIN.example.com" android:scheme="https"/> </intent-filter>
אפשר גם לציין תו כללי כדי להפוך את מסנן Intent לגמיש יותר. לדוגמה:
<intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:host="*.example.com" android:scheme="http"/> <data android:host="*.example.com" android:scheme="https"/> </intent-filter>
כשמשתמשים מקישים על התראה שמכילה קישור לסכימה ולמארח שציינתם, האפליקציה שלכם תתחיל את ה-Activity עם מסנן Intent זה כדי לטפל בקישור.
השלבים הבאים
אחרי שמסיימים את שלבי ההגדרה, הנה כמה אפשרויות להמשך העבודה עם FCM עבור C++: