ตั้งค่าแอปไคลเอ็นต์ Firebase Cloud Messaging ด้วย C++

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

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

Android

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

    • ในวิธีการตั้งค่าที่ลิงก์ไว้ ให้ตรวจสอบข้อกำหนดของอุปกรณ์และแอปในการใช้ Firebase C++ SDK รวมถึงคําแนะนําให้ใช้ CMake เพื่อสร้างแอป

    • ในไฟล์ build.gradle ระดับโปรเจ็กต์ ให้ตรวจสอบว่าได้ใส่ที่เก็บ Maven ของ Google ไว้ทั้งในส่วน buildscript และ allprojects

  2. สร้างออบเจ็กต์แอป Firebase โดยส่งผ่านสภาพแวดล้อม JNI และ Activity

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

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

  4. เริ่มต้น FCM โดยส่ง App และ Listener ที่สร้างขึ้น

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

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

iOS ขึ้นไป

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

    1. ในโปรเจ็กต์ในคอนโซล Firebase ให้เลือกไอคอนรูปเฟือง เลือกการตั้งค่าโปรเจ็กต์ แล้วเลือกแท็บการรับส่งข้อความระบบคลาวด์

    2. ในส่วนคีย์การตรวจสอบสิทธิ์ APNs ใต้การกำหนดค่าแอป iOS ให้คลิกปุ่มอัปโหลด

    3. เรียกดูตำแหน่งที่คุณบันทึกคีย์ไว้ เลือกคีย์ แล้วคลิกเปิด เพิ่มรหัสคีย์สำหรับคีย์ (ดูได้ใน ศูนย์สมาชิกนักพัฒนาแอปของ Apple) แล้วคลิกอัปโหลด

  3. กำหนดค่าโปรเจ็กต์ Xcode เพื่อเปิดใช้ข้อความ Push โดยทำดังนี้

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

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

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

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

      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 Cloud Messaging ระบบจะขอโทเค็นการลงทะเบียนสําหรับอินสแตนซ์แอปไคลเอ็นต์ แอปจะได้รับโทเค็นที่มี callback ของ OnTokenReceived ซึ่งควรกำหนดไว้ในคลาสที่ใช้ firebase::messaging::Listener

หากต้องการกําหนดเป้าหมายอุปกรณ์ที่เฉพาะเจาะจง คุณจะต้องเข้าถึงโทเค็นนี้

หมายเหตุเกี่ยวกับการนำส่งข้อความใน Android

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

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

หลังจากตั้งค่าแอปไคลเอ็นต์แล้ว คุณก็พร้อมที่จะส่งข้อความดาวน์สตรีมและข้อความตามหัวข้อด้วย Firebase ดูข้อมูลเพิ่มเติมได้จากการแสดงฟังก์ชันการทำงานนี้ในตัวอย่างการเริ่มต้นใช้งานอย่างรวดเร็วซึ่งคุณสามารถดาวน์โหลด เรียกใช้ และตรวจสอบได้

หากต้องการเพิ่มลักษณะการทํางานขั้นสูงอื่นๆ ในแอป โปรดดูคู่มือการส่งข้อความจากเซิร์ฟเวอร์แอป

โปรดทราบว่าคุณจะต้องติดตั้งใช้งานเซิร์ฟเวอร์จึงจะใช้ฟีเจอร์เหล่านี้ได้