คู่มือนี้อธิบายวิธีตั้งค่า Firebase Cloud Messaging ในแอปไคลเอ็นต์บนอุปกรณ์เคลื่อนที่และเว็บ เพื่อให้คุณรับข้อความได้อย่างน่าเชื่อถือ
หากต้องการรับข้อความ ให้ใช้บริการที่ขยาย
FirebaseMessagingService
บริการของคุณควรลบล้างการเรียกกลับ onMessageReceived
และ onDeletedMessages
onMessageReceived
มีให้ใช้งานสำหรับข้อความส่วนใหญ่ โดยมีข้อยกเว้นต่อไปนี้
ข้อความแจ้งเตือนที่ส่งเมื่อแอปทำงานอยู่เบื้องหลัง ในกรณีนี้ ระบบจะส่งการแจ้งเตือนไปยังถาดระบบของอุปกรณ์ ผู้ใช้แตะ การแจ้งเตือนจะเปิดตัวเปิดแอปโดยค่าเริ่มต้น
ข้อความที่มีทั้งเพย์โหลดการแจ้งเตือนและเพย์โหลดข้อมูลเมื่อได้รับใน เบื้องหลัง ในกรณีนี้ ระบบจะส่งการแจ้งเตือนไปยังถาดระบบของอุปกรณ์ และส่งเพย์โหลดข้อมูลในส่วนพิเศษของ Intent ของกิจกรรมตัวเรียกใช้งาน
บทสรุปมีดังนี้:
สถานะของแอป | การแจ้งเตือน | ข้อมูล | ทั้งสอง |
---|---|---|---|
พื้นหน้า | onMessageReceived |
onMessageReceived |
onMessageReceived |
ข้อมูลเบื้องต้น | ถาดระบบ | onMessageReceived |
การแจ้งเตือน: ข้อมูลถาดระบบ: ในส่วนพิเศษของ Intent |
ดูข้อมูลเพิ่มเติมเกี่ยวกับประเภทข้อความได้ที่การแจ้งเตือนและข้อความข้อมูล
onMessageReceived
Callback จะมีระยะหมดเวลาที่ช่วยให้คุณ
โพสต์การแจ้งเตือนได้ แต่ตัวจับเวลาไม่ได้ออกแบบมาเพื่อให้แอปเข้าถึง
เครือข่ายหรือทำงานเพิ่มเติมได้ ดังนั้น หากแอปของคุณทำอะไรที่ซับซ้อนกว่านี้ คุณจะต้องทำงานเพิ่มเติมเพื่อให้แน่ใจว่าแอปจะทำงานให้เสร็จสมบูรณ์ได้
หากคาดว่าแอปอาจต้องใช้เวลาเกือบ 10 วินาทีในการจัดการข้อความ
คุณควรตั้งเวลา作業管理
作業 หรือ
ทำตามคำแนะนำเกี่ยวกับ WakeLock
ด้านล่าง ในบางกรณี กรอบเวลาในการจัดการข้อความอาจสั้นกว่า 10 วินาที ทั้งนี้ขึ้นอยู่กับ
ความล่าช้าที่เกิดขึ้นก่อนการเรียกใช้ onMessageReceived
ซึ่งรวมถึงความล่าช้าของระบบปฏิบัติการ เวลาเริ่มต้นของแอป เธรดหลักถูกบล็อกโดยการดำเนินการอื่นๆ หรือการเรียกใช้ onMessageReceived
ก่อนหน้านี้ใช้เวลานานเกินไป หลังจากตัวจับเวลาหมดอายุ แอปของคุณอาจต้องสิ้นสุดกระบวนการหรือมีข้อจำกัดในการเรียกใช้ในเบื้องหลัง โปรดทราบว่าเวลาในการตอบสนองสำหรับการทำธุรกรรมในเครือข่ายและการเริ่มต้นแอปอาจนานมาก ดังนั้นหากไม่แน่ใจ ให้วางแผนการประมวลผลข้อความให้ใช้เวลานานหากมีการขึ้นต่อกันแบบไม่พร้อมกัน เช่น การเข้าถึงเครือข่ายหรือข้อกำหนดในการโหลดข้อมูลจำนวนมาก
แก้ไขไฟล์ Manifest ของแอป
หากต้องการใช้ FirebaseMessagingService
คุณต้องเพิ่มข้อมูลต่อไปนี้ในไฟล์ Manifest ของแอป
<service
android:name=".java.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
นอกจากนี้ เราขอแนะนําให้คุณตั้งค่าเริ่มต้นเพื่อปรับแต่งลักษณะที่ปรากฏของ การแจ้งเตือน คุณระบุไอคอนเริ่มต้นที่กำหนดเองและสีเริ่มต้นที่กำหนดเอง ซึ่งจะใช้เมื่อใดก็ตามที่ไม่ได้ตั้งค่าที่เทียบเท่าในเพย์โหลด การแจ้งเตือน
เพิ่มบรรทัดต่อไปนี้ภายในแท็ก application
เพื่อตั้งค่าไอคอนเริ่มต้นที่กำหนดเองและ
สีที่กำหนดเอง
<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
See README(https://goo.gl/l4GJaQ) for more. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_ic_notification" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />
Android จะแสดงและใช้ไอคอนเริ่มต้นที่กำหนดเองสำหรับ
- ข้อความแจ้งเตือนทั้งหมดที่ส่งจากเครื่องมือสร้าง การแจ้งเตือน
- ข้อความแจ้งเตือนที่ไม่ได้ตั้งค่าไอคอนอย่างชัดเจนใน เพย์โหลดการแจ้งเตือน
หากไม่ได้ตั้งค่าไอคอนเริ่มต้นที่กำหนดเองและไม่ได้ตั้งค่าไอคอนในเพย์โหลดการแจ้งเตือน Android จะแสดงไอคอนแอปพลิเคชันที่แสดงเป็นสีขาว
ลบล้าง onMessageReceived
การลบล้างเมธอด FirebaseMessagingService.onMessageReceived
จะช่วยให้คุณ
ดำเนินการตาม
ออบเจ็กต์ RemoteMessage
ที่ได้รับและรับข้อมูลข้อความได้
Kotlin
override fun onMessageReceived(remoteMessage: RemoteMessage) { // TODO(developer): Handle FCM messages here. // Not getting messages here? See why this may be: https://goo.gl/39bRNJ Log.d(TAG, "From: ${remoteMessage.from}") // Check if message contains a data payload. if (remoteMessage.data.isNotEmpty()) { Log.d(TAG, "Message data payload: ${remoteMessage.data}") // Check if data needs to be processed by long running job if (needsToBeScheduled()) { // For long-running tasks (10 seconds or more) use WorkManager. scheduleJob() } else { // Handle message within 10 seconds handleNow() } } // Check if message contains a notification payload. remoteMessage.notification?.let { Log.d(TAG, "Message Notification Body: ${it.body}") } // Also if you intend on generating your own notifications as a result of a received FCM // message, here is where that should be initiated. See sendNotification method below. }
Java
@Override public void onMessageReceived(RemoteMessage remoteMessage) { // TODO(developer): Handle FCM messages here. // Not getting messages here? See why this may be: https://goo.gl/39bRNJ Log.d(TAG, "From: " + remoteMessage.getFrom()); // Check if message contains a data payload. if (remoteMessage.getData().size() > 0) { Log.d(TAG, "Message data payload: " + remoteMessage.getData()); if (/* Check if data needs to be processed by long running job */ true) { // For long-running tasks (10 seconds or more) use WorkManager. scheduleJob(); } else { // Handle message within 10 seconds handleNow(); } } // Check if message contains a notification payload. if (remoteMessage.getNotification() != null) { Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody()); } // Also if you intend on generating your own notifications as a result of a received FCM // message, here is where that should be initiated. See sendNotification method below. }
เปิดหน้าจออุปกรณ์ค้างไว้ขณะจัดการข้อความ FCM
หากแอปต้องทำให้อุปกรณ์ตื่นอยู่ขณะประมวลผลข้อความ FCM แอปจะต้องถือ WakeLock ในช่วงเวลานี้ หรือจะต้องสร้างงาน WorkManager WakeLock เหมาะสำหรับกิจกรรมการประมวลผลสั้นๆ ที่อาจ
เกินระยะหมดเวลาเริ่มต้นของ onMessageReceived
สำหรับเวิร์กโฟลว์ที่ยาวนาน เช่น การส่ง RPC แบบอนุกรมหลายรายการไปยังเซิร์ฟเวอร์ การใช้ งาน WorkManager จะเหมาะสมกว่า WakeLock ในส่วนนี้ เราจะมุ่งเน้นที่วิธีใช้ WakeLock
WakeLock จะป้องกันไม่ให้อุปกรณ์เข้าสู่โหมดสลีประหว่างที่แอปทำงาน ซึ่งอาจ
ส่งผลให้ใช้แบตเตอรี่มากขึ้น ดังนั้นควรใช้ WakeLock เฉพาะใน
กรณีที่แอปไม่ควรหยุดชั่วคราวขณะจัดการข้อความ เช่น
- การแจ้งเตือนที่ต้องดำเนินการทันที
- การโต้ตอบกับสิ่งต่างๆ นอกอุปกรณ์ที่ไม่ควรถูกขัดจังหวะ (เช่น การโอนข้อมูลในเครือข่ายหรือการสื่อสารกับอุปกรณ์อื่น เช่น นาฬิกาที่จับคู่ไว้)
ก่อนอื่น คุณจะต้องตรวจสอบว่าแอปขอสิทธิ์ WakeLock (SDK ของ FCM มีสิทธิ์นี้โดยค่าเริ่มต้น ดังนั้นโดยปกติแล้วจึงไม่จำเป็นต้องเพิ่มอะไร)
<uses-permission android:name="android.permission.WAKE_LOCK" />
จากนั้นแอปจะต้องรับ WakeLock เมื่อเริ่มต้น
FirebaseMessagingService.onMessageReceived()
การเรียกกลับและปล่อยเมื่อสิ้นสุดการเรียกกลับ
FirebaseMessagingService
ที่กำหนดเองของแอป
@Override
public void onMessageReceived(final RemoteMessage message) {
// If this is a message that is time sensitive or shouldn't be interrupted
WakeLock wakeLock = getSystemService(PowerManager.class).newWakeLock(PARTIAL_WAKE_LOCK, "myApp:messageReceived");
try {
wakeLock.acquire(TIMEOUT_MS);
// handle message
...
finally {
wakeLock.release();
}
}
ลบล้าง onDeletedMessages
ในบางกรณี FCM อาจไม่ส่งข้อความ ปัญหานี้เกิดขึ้นเมื่อ
มีข้อความที่รอดำเนินการสำหรับแอปในอุปกรณ์หนึ่งๆ มากเกินไป (>100)
ในขณะที่เชื่อมต่อ หรือหากอุปกรณ์ไม่ได้เชื่อมต่อกับ FCM เป็นเวลา
นานกว่า 1 เดือน ในกรณีเช่นนี้ คุณอาจได้รับการโทรกลับเพื่อ
FirebaseMessagingService.onDeletedMessages()
เมื่ออินสแตนซ์ของแอปได้รับ
Callback นี้ แอปควรทำการซิงค์แบบเต็มกับเซิร์ฟเวอร์ของแอป หากคุณไม่ได้ส่งข้อความไปยังแอปในอุปกรณ์ดังกล่าวภายใน 4 สัปดาห์ที่ผ่านมา FCMจะไม่โทรหาonDeletedMessages()
จัดการข้อความแจ้งเตือนในแอปที่ทำงานเบื้องหลัง
เมื่อแอปทำงานในเบื้องหลัง Android จะส่งข้อความแจ้งเตือนไปยัง ถาดระบบ เมื่อผู้ใช้แตะการแจ้งเตือน ระบบจะเปิดตัวเปิดแอปโดยค่าเริ่มต้น
ซึ่งรวมถึงข้อความที่มีทั้งเพย์โหลดการแจ้งเตือนและเพย์โหลดข้อมูล (และข้อความทั้งหมดที่ส่งจากคอนโซลการแจ้งเตือน) ในกรณีเหล่านี้ ระบบจะส่งการแจ้งเตือน ไปยังถาดระบบของอุปกรณ์ และส่งเพย์โหลดข้อมูลใน ส่วนพิเศษของ Intent ของกิจกรรมตัวเรียกใช้งาน
ดูข้อมูลเชิงลึกเกี่ยวกับการนำส่งข้อความไปยังแอปได้ที่
FCMแดชบอร์ดการรายงาน ซึ่งบันทึก
จำนวนข้อความที่ส่งและเปิดในอุปกรณ์ Apple และ Android พร้อมกับ
ข้อมูลสำหรับ "การแสดงผล" (การแจ้งเตือนที่ผู้ใช้เห็น) สำหรับแอป Android