ตั้งค่าแอปไคลเอ็นต์ 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 และ กิจกรรม:

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

    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 ไปใช้ ของ Google

  6. เริ่มต้นการรับส่งข้อความในระบบคลาวด์ของ Firebase โดยการส่งในแอป และ ผู้ฟัง:

    ::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 จะเป็นค่าว่าง

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

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

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

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

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

ListenerService คือคลาส Java ที่ขัดขวางข้อความขาเข้าที่ส่งไปยังแอปและส่งต่อไปยังไลบรารี C++ เมื่อแอปอยู่เบื้องหน้า (หรือเมื่อแอปอยู่ในเบื้องหลังและได้รับเพย์โหลดเฉพาะข้อมูลเท่านั้น) ข้อความจะส่งผ่าน Callback ที่มีให้ในชั้นเรียนนี้ หากต้องการเพิ่มลักษณะการทำงานที่กำหนดเองให้กับการจัดการข้อความ คุณจะต้องขยาย ListenerService เริ่มต้นของ FCM ดังนี้

import com.google.firebase.messaging.cpp.ListenerService;

class MyListenerService extends ListenerService {

เมื่อลบล้างเมธอด ListenerService.onMessageReceived คุณจะสามารถ ดำเนินการตามรายการที่ได้รับ ข้อความระยะไกล และรับข้อมูลข้อความ:

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

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

โปรดทราบว่าคุณต้องมี การติดตั้งเซิร์ฟเวอร์ เพื่อใช้ประโยชน์จาก ใหม่ๆ