הגדרה של אפליקציית לקוח להעברת הודעות בענן ב-Firebase באמצעות C++

כדי לכתוב אפליקציית לקוח של Firebase Cloud Messaging בפלטפורמות שונות באמצעות C++, צריך להשתמש ב-API של Firebase Cloud Messaging. ה-SDK של C++ פועל גם בפלטפורמות Android וגם Apple, ויש צורך בהגדרות נוספות לכל פלטפורמה.

הגדרת Firebase ו-FCM SDK

Android

  1. אם עדיין לא עשיתם זאת, מוסיפים את Firebase לפרויקט C++‎.

    • בהוראות ההגדרה המקושרות, כדאי לבדוק את הדרישות למכשירים ולאפליקציות לשימוש ב-SDK של Firebase C++, כולל ההמלצה להשתמש ב-CMake כדי ליצור את האפליקציה.

    • בקובץ build.gradle ברמת הפרויקט, חשוב לכלול מאגר Maven של Google גם ב-buildscript וגם allprojects קטעים.

  2. יוצרים אובייקט של אפליקציית Firebase ומעבירים אותו בסביבת JNI פעילות:

    app = ::firebase::App::Create(::firebase::AppOptions(), jni_env, activity);

  3. הגדרת מחלקה שמממשת את firebase::messaging::Listener גרפי.

  4. מאתחלים את FCM, מעבירים את האפליקציה ומאזינים מובנה:

    ::firebase::messaging::Initialize(app, listener);

  5. אפליקציות שמסתמכות על Google Play services SDK צריכות לבדוק במכשיר אם יש חבילת APK תואמת של Google Play Services לפני שהן ניגשות לתכונות. מידע נוסף זמין במאמר הבא: לבדיקת ה-APK של Google Play Services

iOS+

  1. אם עדיין לא עשיתם זאת, מוסיפים את Firebase לפרויקט C++. לאחר מכן, כדי להגדיר את הפרויקט ב-FCM:
    1. מוסיפים את התלות ב-FCM ל-Podfile של הפרויקט:
      pod 'FirebaseMessaging'
    2. גוררים את המסגרות firebase.framework ו-firebase_messaging.framework לפרויקט Xcode מ-Firebase C++ SDK.
  2. מעלים את מפתח האימות של APNs ל-Firebase. אם עדיין אין לכם מפתח אימות של APN, עליכם ליצור אותו מרכז המנויים למפתחי Apple.

    1. בתוך הפרויקט במסוף Firebase, לוחצים על סמל גלגל השיניים, בוחרים באפשרות Project Settings ואז בוחרים בכרטיסייה Cloud Messaging.

    2. במפתח אימות של APNs בקטע הגדרת אפליקציה ל-iOS, לוחצים על העלאה לחצן.

    3. עליך לעבור למיקום שבו שמרת את המפתח, לבחור אותו וללחוץ על פתיחה. מוסיפים את מזהה המפתח של המפתח (זמין Apple Developer Member Center) ולוחצים על העלאה.

  3. מגדירים את פרויקט ה-Xcode כדי להפעיל התראות:

    1. בוחרים את הפרויקט מאזור הניווט.
    2. בוחרים את יעד הפרויקט באזור העורך.
    3. בוחרים את הכרטיסייה כללי מתוך אזור העריכה.

      1. גוללים למטה לקטע Linked Frameworks and Libraries (מסגרות וספריות מקושרות) ולוחצים על הלחצן + כדי להוסיף מסגרות.
      2. בחלון שמופיע, גוללים אל UserNotifications.framework, לוחצים על הרשומה הזו ואז לוחצים על Add.

        המסגרת הזו מופיעה רק ב-Xcode מגרסה 8 ואילך, והיא נדרשת לספרייה הזו.

    4. באזור העריכה, בוחרים בכרטיסייה יכולות.

      1. מעבירים את המתג שליד התראות למצב מופעל.
      2. גוללים למטה אל מצבי רקע ומעבירים את המתג למצב מופעל.
      3. בקטע מצבי רקע, בוחרים באפשרות התראות מרחוק.
  4. יוצרים אובייקט של אפליקציית Firebase:

    app = ::firebase::App::Create(::firebase::AppOptions());

  5. הגדרת מחלקה שמממשת את firebase::messaging::Listener גרפי.

  6. מפעילים את Firebase Cloud Messaging ומעבירים את האפליקציה ואת ה-Listener שנוצר:

    ::firebase::messaging::Initialize(app, listener);

גישה לטוקן הרישום של המכשיר

בזמן האתחול של ספריית Firebase Cloud Messaging, מתבצע בקשה לקבלת אסימון רישום למכונה של אפליקציית הלקוח. האפליקציה תקבל את האסימון עם קריאה חוזרת של OnTokenReceived, שצריך להגדיר במחלקה שמטמיעה firebase::messaging::Listener.

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

הערה לגבי שליחת הודעות ב-Android

כשהאפליקציה לא פועלת בכלל והמשתמש מקיש על התראה, כברירת מחדל, ההודעה לא מנותבת דרך הכלים המובנים של FCM קריאה חוזרת (callback). במקרה הזה, מטענים ייעודיים של הודעות מתקבלים באמצעות Intent ששימש להפעלת האפליקציה. כדי ש-FCM יעביר את ההודעות הנכנסות האלה ל-callback של ספריית ה-C++, צריך לשנות את השיטה onNewIntent ב-Activity ולהעביר את 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 שיטות.

ListenerService הוא מחלקה של Java שמיירט הודעות נכנסות שנשלחות אל את האפליקציה ומפנה אותם לספריית C++. כשהאפליקציה פתוחה בחזית (או כשהאפליקציה פועלת ברקע ומקבלת עומס נתונים בלבד), ההודעות עוברות דרך אחת מהקריאות החוזרות (callbacks) שסופקו בכיתה הזו. כדי להוסיף התנהגות מותאמת אישית לטיפול בהודעות, צריך להרחיב את ListenerService שמוגדרת כברירת מחדל ב-FCM:

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 הזה ב: שירות cusom להאזנה. ניתן לעשות זאת על ידי הסרת ברירת המחדל 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) בפלטפורמות של Apple, או ב-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::SetTokenRegistrationOnInitEnabled(true);

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

התכונה 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>

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

השלבים הבאים

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

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

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