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

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


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

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

ตั้งค่า 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 โดยส่งแอปและ 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

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

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

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

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

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

      1. เปลี่ยนข้อความ Push เป็นเปิด
      2. เลื่อนไปที่โหมดเบื้องหลัง แล้วเปลี่ยนเป็นเปิด
      3. เลือกการแจ้งเตือนระยะไกลในส่วนโหมดพื้นหลัง
  4. สร้างออบเจ็กต์ Firebase App

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

  5. กำหนดคลาสที่ใช้firebase::messaging::Listener อินเทอร์เฟซ

  6. เริ่มต้น Firebase Cloud Messaging โดยส่ง App และ 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

ใช้ onRegistrationReceived Listener

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

บทสรุปมีดังนี้:

สถานะแอป การแจ้งเตือน ข้อมูล ทั้งสอง
เบื้องหน้า OnMessageReceived OnMessageReceived OnMessageReceived
ข้อมูลเบื้องต้น ถาดระบบ OnMessageReceived การแจ้งเตือน: ถาดระบบ
ข้อมูล: ในส่วนพิเศษของ Intent

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

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

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

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

เมื่อผู้ใช้แตะการแจ้งเตือนที่มีลิงก์ไปยัง Scheme และโฮสต์ที่คุณระบุ แอปจะเริ่มกิจกรรมด้วยตัวกรอง Intent นี้เพื่อจัดการลิงก์

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

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