เริ่มต้นใช้งาน Firebase Cloud Messaging ในแอป C++

เลือกแพลตฟอร์ม: iOS+ Android Web Flutter Unity C++


คู่มือนี้อธิบายวิธีเริ่มต้นใช้งาน Firebase Cloud Messaging ในแอปไคลเอ็นต์ C++ ของคุณ เพื่อให้คุณส่งข้อความได้อย่างน่าเชื่อถือ

หากต้องการเขียนแอปไคลเอ็นต์ Firebase Cloud Messaging ข้ามแพลตฟอร์มด้วย C++ ให้ใช้ Firebase Cloud Messaging API SDK ของ C++ ใช้งานได้กับทั้งแพลตฟอร์ม Android และ Apple โดยต้องมีการตั้งค่าเพิ่มเติมสำหรับแต่ละแพลตฟอร์ม ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่ SDK ของ C++ สำหรับ iOS และ Android ทำงานร่วมกับ FCM ได้ที่ ทำความเข้าใจ Firebase สำหรับ C++

ตั้งค่า Firebase และ FCM SDK

Android

  1. เพิ่ม Firebase ลงในโปรเจ็กต์ C++ หากยังไม่ได้เพิ่ม

    • ในวิธีการตั้งค่าที่ลิงก์ไว้ ให้ตรวจสอบข้อกำหนดของอุปกรณ์และแอป สำหรับการใช้ Firebase C++ SDK รวมถึงคำแนะนำให้ใช้ 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 โดยส่งแอปและ Listener ที่สร้างขึ้น

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

  5. แอปที่ใช้ SDK ของบริการ Google Play ควรตรวจสอบว่าอุปกรณ์มี APK ของบริการ Google Play ที่เข้ากันได้ก่อนที่จะเข้าถึงฟีเจอร์ ดูข้อมูลเพิ่มเติมได้ที่ ตรวจสอบ APK ของบริการ Google Play

iOS+

  1. เพิ่ม Firebase ลงในโปรเจ็กต์ C++ หากยังไม่ได้เพิ่ม จากนั้น ตั้งค่าโปรเจ็กต์สำหรับ FCM โดยทำดังนี้
    1. เพิ่มทรัพยากร Dependency ของ FCM ลงใน Podfile ของโปรเจ็กต์
      pod 'FirebaseMessaging'
    2. ลากเฟรมเวิร์ก firebase.framework และ firebase_messaging.framework ไปยังโปรเจ็กต์ Xcode จาก Firebase C++ SDK
  2. อัปโหลดคีย์การตรวจสอบสิทธิ์ APNs ไปยัง Firebase หากยังไม่มีคีย์การตรวจสอบสิทธิ์ APNs โปรดสร้างคีย์ใน Apple Developer Member Center

    1. ในคอนโซล Firebase ให้ไปที่ การตั้งค่า > ทั่วไป จากนั้นคลิกแท็บ Cloud Messaging
    2. ในส่วนคีย์การตรวจสอบสิทธิ์ APNs ในส่วนการกำหนดค่าแอป iOS ให้คลิกอัปโหลด เพื่ออัปโหลดคีย์การตรวจสอบสิทธิ์สำหรับการพัฒนา คีย์การตรวจสอบสิทธิ์สำหรับการใช้งานจริง หรือทั้ง 2 อย่าง คุณต้องอัปโหลดอย่างน้อย 1 คีย์
    3. เรียกดูตำแหน่งที่คุณบันทึกคีย์ เลือกคีย์ แล้วคลิก เปิด เพิ่มรหัสคีย์สำหรับคีย์ (มีอยู่ใน Apple Developer Member Center) แล้วคลิก อัปโหลด
  3. กำหนดค่าโปรเจ็กต์ Xcode เพื่อเปิดใช้ข้อความ Push โดยทำดังนี้

    1. เลือกโปรเจ็กต์จากพื้นที่ Navigator
    2. เลือกเป้าหมายของโปรเจ็กต์จากพื้นที่ Editor
    3. เลือกแท็บทั่วไป จากพื้นที่ Editor

      1. เลื่อนไปที่เฟรมเวิร์กและไลบรารีที่ลิงก์ แล้วคลิก ปุ่ม + เพื่อเพิ่มเฟรมเวิร์ก
      2. ในหน้าต่างที่ปรากฏขึ้น ให้เลื่อนไปที่ UserNotifications.framework คลิกรายการ แล้วคลิก เพิ่ม

        เฟรมเวิร์กนี้จะปรากฏใน Xcode เวอร์ชัน 8 ขึ้นไปเท่านั้น และไลบรารีนี้จำเป็นต้องใช้

    4. เลือกแท็บความสามารถ จากพื้นที่ Editor

      1. เปลี่ยนข้อความ Push เป็นเปิด
      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

เปิดใช้การลงทะเบียนโดยใช้รหัสการติดตั้ง Firebase

หากต้องการเปิดใช้การลงทะเบียนอินสแตนซ์ของแอปกับ FCM โดยใช้ Firebase รหัสการติดตั้ง (FID) คุณต้อง เปิดใช้ FID ในการกำหนดค่าของแอปสำหรับทั้งแพลตฟอร์ม 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 พร้อมการเรียกกลับ 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 ระบบจะขอโทเค็นการลงทะเบียน สำหรับอินสแตนซ์ของแอปไคลเอ็นต์ แอปจะได้รับโทเค็นพร้อมการเรียกกลับ 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 การแจ้งเตือน: ถาดระบบ
ข้อมูล: ในส่วนเพิ่มเติมของ Intent

การจัดการข้อความที่กำหนดเองใน Android

โดยค่าเริ่มต้น ระบบจะส่งการแจ้งเตือนที่ส่งไปยังแอปไปยัง ::firebase::messaging::Listener::OnMessageReceived แต่ในบางกรณี คุณอาจต้องการลบล้างลักษณะการทำงานเริ่มต้น หากต้องการทำเช่นนี้ใน Android คุณจะต้องเขียนคลาสที่กำหนดเองซึ่งขยาย com.google.firebase.messaging.cpp.ListenerService รวมถึงอัปเดต AndroidManifest.xml ของโปรเจ็กต์

ลบล้างเมธอด ListenerService

ListenerService คือคลาส Java ที่สกัดกั้นข้อความขาเข้าที่ส่งไปยังแอปและกำหนดเส้นทางข้อความไปยังไลบรารี C++ เมื่อแอปทำงานอยู่เบื้องหน้า (หรือเมื่อแอปทำงานอยู่เบื้องหลังและได้รับเพย์โหลดที่มีข้อมูลเท่านั้น) ข้อความจะส่งผ่านการเรียกกลับรายการใดรายการหนึ่งที่ระบุไว้ในคลาสนี้ หากต้องการเพิ่ม ลักษณะการทำงานที่กำหนดเองลงในการจัดการข้อความ คุณจะต้องขยาย FCM's เริ่มต้น 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 ยังมีเมธอดอื่นๆ อีก 2-3 รายการที่ใช้ไม่บ่อยนัก คุณสามารถลบล้างเมธอดเหล่านี้ได้เช่นกัน ดูข้อมูลเพิ่มเติมได้ที่ข้อมูลอ้างอิง 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> ดังนี้

<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 โดยปกติแล้ว Manifest นี้จะผสานกับ Manifest ที่เฉพาะเจาะจงของโปรเจ็กต์ ซึ่งเป็นวิธีที่ ListenerService ทำงานได้ คุณต้องแทนที่ ListenerService นี้ด้วยบริการ Listener ที่กำหนดเอง ซึ่งทำได้โดยนำ 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 (และ Analytics ใน Android) หากต้องการทำเช่นนี้ ให้เพิ่มค่าข้อมูลเมตาลงใน ของคุณ 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::SetRegistrationOnInitEnabled(true);

ค่านี้จะยังคงอยู่เมื่อรีสตาร์ทแอปหลังจากตั้งค่าแล้ว

FCM อนุญาตให้ส่งข้อความที่มี Deep Link ไปยังแอปได้ หากต้องการรับข้อความที่มี Deep Link คุณต้องเพิ่มตัวกรอง Intent ใหม่ ลงในกิจกรรมที่จัดการ Deep Link สำหรับแอป ตัวกรอง Intent ควร ดักจับ Deep Link ของโดเมน หากข้อความไม่มี Deep Link คุณก็ไม่จำเป็นต้องกำหนดค่านี้ ใน 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 นี้เพื่อจัดการลิงก์

ขั้นตอนถัดไป

หลังจากทำตามขั้นตอนการตั้งค่าเสร็จแล้ว คุณสามารถเลือกตัวเลือกต่อไปนี้เพื่อดำเนินการต่อกับ FCM สำหรับ C++: