| เลือกแพลตฟอร์ม: | 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
เพิ่ม Firebase ลงในโปรเจ็กต์ C++ หากยังไม่ได้เพิ่ม
ในวิธีการตั้งค่าที่ลิงก์ไว้ ให้อ่านข้อกําหนดของอุปกรณ์และแอป สําหรับการใช้ SDK ของ Firebase C++ รวมถึงคําแนะนํา ให้ใช้ CMake เพื่อสร้างแอป
ในไฟล์
build.gradleระดับโปรเจ็กต์ ให้ตรวจสอบว่าได้รวมที่เก็บ Maven ของ Google ไว้ในทั้งส่วนbuildscriptและallprojects
สร้างออบเจ็กต์แอป Firebase โดยส่งสภาพแวดล้อม JNI และ กิจกรรม:
app = ::firebase::App::Create(::firebase::AppOptions(), jni_env, activity);
กำหนดคลาสที่ใช้
firebase::messaging::Listenerอินเทอร์เฟซเริ่มต้น FCM โดยส่งแอปและ Listener ที่สร้างขึ้น
::firebase::messaging::Initialize(app, listener);
แอปที่ใช้ SDK ของบริการ Google Play ควรตรวจสอบอุปกรณ์ เพื่อหา APK ของบริการ Google Play ที่เข้ากันได้ก่อนเข้าถึงฟีเจอร์ ดูข้อมูลเพิ่มเติมได้ที่ตรวจสอบ APK ของบริการ Google Play
iOS+
- เพิ่ม Firebase ลงในโปรเจ็กต์ C++ หากยังไม่ได้เพิ่ม จากนั้น
หากต้องการตั้งค่าโปรเจ็กต์สำหรับ FCM ให้ทำดังนี้
- เพิ่มทรัพยากร Dependency ของ FCM ใน Podfile ของโปรเจ็กต์
pod 'FirebaseMessaging'
- ลากเฟรมเวิร์ก
firebase.frameworkและfirebase_messaging.frameworkไปยังโปรเจ็กต์ Xcode จาก Firebase C++ SDK
- เพิ่มทรัพยากร Dependency ของ FCM ใน Podfile ของโปรเจ็กต์
อัปโหลดคีย์การตรวจสอบสิทธิ์ APNs ไปยัง Firebase หากยังไม่มีคีย์การตรวจสอบสิทธิ์ APNs ให้สร้างคีย์ในศูนย์สมาชิก Apple Developer
-
ในFirebaseคอนโซล ให้ไปที่
การตั้งค่า > ทั่วไป จากนั้นคลิกแท็บ Cloud Messaging - ในคีย์การตรวจสอบสิทธิ์ APNs ภายในการกำหนดค่าแอป iOS คลิกอัปโหลดเพื่ออัปโหลดคีย์การตรวจสอบสิทธิ์สำหรับการพัฒนา หรือ คีย์การตรวจสอบสิทธิ์สำหรับการใช้งานจริง หรือทั้ง 2 อย่าง ทั้งนี้คุณต้องระบุอย่างน้อย 1 รายการ
- เรียกดูตำแหน่งที่คุณบันทึกคีย์ เลือกคีย์ แล้วคลิกเปิด เพิ่มรหัสคีย์สำหรับคีย์ (มีอยู่ใน ศูนย์สมาชิก Apple Developer) แล้วคลิกอัปโหลด
-
ในFirebaseคอนโซล ให้ไปที่
กำหนดค่าโปรเจ็กต์ Xcode เพื่อเปิดใช้ข้อความ Push โดยทำดังนี้
- เลือกโปรเจ็กต์จากพื้นที่แถบนำทาง
- เลือกเป้าหมายของโปรเจ็กต์จากพื้นที่แก้ไข
เลือกแท็บทั่วไปจากพื้นที่แก้ไข
- เลื่อนไปที่เฟรมเวิร์กและไลบรารีที่ลิงก์ แล้วคลิกปุ่ม + เพื่อเพิ่มเฟรมเวิร์ก
ในหน้าต่างที่ปรากฏขึ้น ให้เลื่อนไปที่ UserNotifications.framework คลิกรายการ แล้วคลิก เพิ่ม
เฟรมเวิร์กนี้จะปรากฏใน Xcode v8 ขึ้นไปเท่านั้น และไลบรารีนี้จำเป็นต้องใช้
เลือกแท็บความสามารถจากพื้นที่แก้ไข
- เปลี่ยนข้อความ Push เป็นเปิด
- เลื่อนไปที่โหมดเบื้องหลัง แล้วเปลี่ยนเป็นเปิด
- เลือกการแจ้งเตือนระยะไกลในส่วนโหมดพื้นหลัง
สร้างออบเจ็กต์ Firebase App
app = ::firebase::App::Create(::firebase::AppOptions());
กำหนดคลาสที่ใช้
firebase::messaging::Listenerอินเทอร์เฟซเริ่มต้น 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);
ค่านี้จะยังคงอยู่เมื่อรีสตาร์ทแอปเมื่อตั้งค่าแล้ว
ข้อความที่มี Deep Link ใน Android
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++