การแจ้งเตือนของ Firebase จะทำงานแตกต่างกันไปขึ้นอยู่กับสถานะเบื้องหน้า / พื้นหลังของแอปที่รับ หากคุณต้องการให้แอปเบื้องหน้ารับข้อความแจ้งเตือนหรือข้อความข้อมูลคุณจะต้องเขียนโค้ดเพื่อจัดการกับการโทรกลับ onMessageReceived
สำหรับคำอธิบายเกี่ยวกับความแตกต่างระหว่างการแจ้งเตือนและข้อความข้อมูลโปรดดูที่ ประเภทข้อความ
การจัดการข้อความ
หากต้องการรับข้อความให้ใช้บริการที่ขยาย FirebaseMessagingService บริการของคุณควรแทนที่การเรียกกลับ onMessageReceived
และ onDeletedMessages
ควรจัดการข้อความใด ๆ ภายใน 20 วินาทีหลังจากได้รับ (10 วินาทีบน Android Marshmallow) หน้าต่างเวลาอาจสั้นลงขึ้นอยู่กับความล่าช้าของระบบปฏิบัติการที่เกิดขึ้นก่อนที่จะเรียก onMessageReceived
หลังจากนั้นพฤติกรรมต่างๆของระบบปฏิบัติการเช่น ขีด จำกัด การดำเนินการเบื้องหลัง ของ Android O อาจรบกวนความสามารถในการทำงานให้เสร็จสิ้น สำหรับข้อมูลเพิ่มเติมโปรดดูภาพรวมของเราเกี่ยวกับ ลำดับความสำคัญของข้อความ
onMessageReceived
มีไว้สำหรับประเภทข้อความส่วนใหญ่โดยมีข้อยกเว้นดังต่อไปนี้:
ส่งข้อความแจ้งเตือนเมื่อแอปของคุณอยู่เบื้องหลัง ในกรณีนี้การแจ้งเตือนจะถูกส่งไปยังซิสเต็มเทรย์ของอุปกรณ์ ผู้ใช้แตะที่การแจ้งเตือนจะเปิดตัวเรียกใช้งานแอปตามค่าเริ่มต้น
ข้อความที่มีทั้งการแจ้งเตือนและเพย์โหลดข้อมูลเมื่อได้รับในพื้นหลัง ในกรณีนี้การแจ้งเตือนจะถูกส่งไปยังซิสเต็มเทรย์ของอุปกรณ์และเพย์โหลดข้อมูลจะถูกส่งไปตามความตั้งใจของกิจกรรมตัวเรียกใช้งานของคุณ
สรุป:
สถานะของแอป | การแจ้งเตือน | ข้อมูล | ทั้งสอง |
---|---|---|---|
เบื้องหน้า | onMessageReceived | onMessageReceived | onMessageReceived |
พื้นหลัง | ถาดระบบ | onMessageReceived | การแจ้งเตือน: ถาดระบบ ข้อมูล: นอกเหนือจากเจตนา |
แก้ไขรายการแอพ
ในการใช้ FirebaseMessagingService
คุณต้องเพิ่มสิ่งต่อไปนี้ในรายการแอปของคุณ:
<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 ใช้สีเริ่มต้นที่กำหนดเองสำหรับ
- ข้อความแจ้งเตือนทั้งหมดที่ส่งจากผู้ เรียบเรียงการแจ้งเตือน
- ข้อความแจ้งเตือนใด ๆ ที่ไม่ได้กำหนดสีในเพย์โหลดการแจ้งเตือนอย่างชัดเจน
หากไม่มีการตั้งค่าไอคอนเริ่มต้นที่กำหนดเองและไม่มีการตั้งค่าไอคอนในเพย์โหลดการแจ้งเตือน Android จะแสดงไอคอนแอปพลิเคชันเป็นสีขาว
แทนที่ onMessageReceived
ด้วยการแทนที่เมธอด FirebaseMessagingService.onMessageReceived
คุณสามารถดำเนินการตามวัตถุ RemoteMessage ที่ ได้รับและรับข้อมูลข้อความ:
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. }
โคตรลิน + KTX
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}") 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. 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. }
แทนที่ onDeletedMessages
ในบางสถานการณ์ FCM อาจไม่ส่งข้อความ กรณีนี้เกิดขึ้นเมื่อมีข้อความจำนวนมากเกินไป (> 100) รอดำเนินการสำหรับแอปของคุณบนอุปกรณ์บางเครื่องในขณะที่เชื่อมต่อหรือหากอุปกรณ์ไม่ได้เชื่อมต่อกับ FCM เป็นเวลานานกว่าหนึ่งเดือน ในกรณีเหล่านี้คุณอาจได้รับการติดต่อกลับไปที่ FirebaseMessagingService.onDeletedMessages()
เมื่ออินสแตนซ์ของแอปได้รับการโทรกลับนี้ควรทำการซิงค์อย่างสมบูรณ์กับเซิร์ฟเวอร์แอปของคุณ หากคุณไม่ได้ส่งข้อความไปยังแอปบนอุปกรณ์นั้นภายใน 4 สัปดาห์ที่ผ่านมา FCM จะไม่โทรหา onDeletedMessages()
จัดการข้อความแจ้งเตือนในแอพที่มีพื้นหลัง
เมื่อแอปของคุณทำงานอยู่เบื้องหลัง Android จะส่งข้อความแจ้งเตือนไปที่ซิสเต็มเทรย์ ผู้ใช้แตะที่การแจ้งเตือนจะเปิดตัวเรียกใช้งานแอปตามค่าเริ่มต้น
ซึ่งรวมถึงข้อความที่มีทั้งส่วนการแจ้งเตือนและข้อมูล (และข้อความทั้งหมดที่ส่งจากคอนโซลการแจ้งเตือน) ในกรณีเหล่านี้การแจ้งเตือนจะถูกส่งไปยังซิสเต็มเทรย์ของอุปกรณ์และเพย์โหลดข้อมูลจะถูกส่งไปตามจุดประสงค์ของกิจกรรมตัวเรียกใช้งานของคุณ
สำหรับข้อมูลเชิงลึกเกี่ยวกับการส่งข้อความไปยังแอปของคุณโปรดดู แดชบอร์ดการรายงาน FCM ซึ่งบันทึกจำนวนข้อความที่ส่งและเปิดบนอุปกรณ์ iOS และ Android พร้อมกับข้อมูลสำหรับ "การแสดงผล" (การแจ้งเตือนที่ผู้ใช้เห็น) สำหรับแอป Android
แอปที่ จำกัด พื้นหลัง (Android P หรือใหม่กว่า)
FCM อาจไม่ส่งข้อความไปยังแอปที่ผู้ใช้กำหนดไว้ใน พื้นหลัง (เช่นผ่าน: การตั้งค่า -> แอปและการแจ้งเตือน -> [ชื่อแอป] -> แบตเตอรี่) เมื่อแอปของคุณถูกลบออกจากการ จำกัด พื้นหลังข้อความใหม่ที่ส่งไปยังแอปจะถูกส่งเหมือนเดิม เพื่อป้องกันข้อความสูญหายและผลกระทบจากการ จำกัด พื้นหลังอื่น ๆ อย่าลืมหลีกเลี่ยงพฤติกรรมที่ไม่ดีตามความพยายามของ Android Vitals พฤติกรรมเหล่านี้อาจทำให้อุปกรณ์ Android แนะนำให้ผู้ใช้ทราบว่าแอปของคุณถูก จำกัด พื้นหลัง แอปของคุณสามารถตรวจสอบว่ามีการ จำกัด พื้นหลังหรือไม่โดยใช้: isBackgroundRestricted ()รับข้อความ FCM ในโหมดบูตโดยตรง
นักพัฒนาที่ต้องการส่งข้อความ FCM ไปยังแอปก่อนที่อุปกรณ์จะปลดล็อกสามารถเปิดใช้งานแอป Android เพื่อรับข้อความเมื่ออุปกรณ์อยู่ในโหมดบูตโดยตรง ตัวอย่างเช่นคุณอาจต้องการให้ผู้ใช้แอปของคุณได้รับการแจ้งเตือนแม้ในอุปกรณ์ที่ล็อกอยู่
เมื่อสร้างกรณีการใช้งานนี้ให้ปฏิบัติตาม แนวทางปฏิบัติที่ดีที่สุด ทั่วไป และข้อ จำกัด สำหรับโหมดบูตโดยตรง สิ่งสำคัญอย่างยิ่งที่จะต้องพิจารณาการ เปิดเผย ข้อความที่เปิดใช้งานการบูตโดยตรง ผู้ใช้ที่มีสิทธิ์เข้าถึงอุปกรณ์สามารถดูข้อความเหล่านี้ได้โดยไม่ต้องป้อนข้อมูลรับรองผู้ใช้
ข้อกำหนดเบื้องต้น
- ต้องตั้งค่าอุปกรณ์สำหรับโหมดบูตโดยตรง
- อุปกรณ์ต้องติดตั้งบริการ Google Play เวอร์ชันล่าสุด (19.0.54 หรือใหม่กว่า)
- แอปต้องใช้ FCM SDK (
com.google.firebase:firebase-messaging
) เพื่อรับข้อความ FCM
เปิดใช้งานการจัดการข้อความโหมดบูตโดยตรงในแอปของคุณ
ในไฟล์ Gradle ระดับแอปเพิ่มการพึ่งพาไลบรารีสนับสนุนการบูตโดยตรงของ FCM:
implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
ทำให้
07bdca 0870FirebaseMessagingService
ทราบการบูตโดยตรงของแอปโดยการเพิ่มแอตทริบิวต์android:directBootAware="true"
ในรายการแอป:
สิ่งสำคัญคือต้องตรวจสอบให้แน่ใจว่า FirebaseMessagingService
นี้สามารถทำงานในโหมดบูตโดยตรงได้ ตรวจสอบข้อกำหนดต่อไปนี้:
- บริการไม่ควรเข้าถึงที่เก็บข้อมูลที่มีการป้องกันข้อมูลประจำตัวในขณะที่ทำงานในโหมดบูตโดยตรง
- บริการไม่ควรพยายามใช้คอมโพเนนต์เช่น
Activities
,BroadcastReceivers
หรือServices
อื่น ๆ ที่ไม่ได้ทำเครื่องหมายว่าเป็น Direct Boot Aware ขณะทำงานในโหมด Direct Boot - ไลบรารีใด ๆ ที่ใช้บริการจะต้องไม่เข้าถึงหน่วยเก็บข้อมูลที่มีการป้องกันข้อมูลประจำตัวหรือเรียกใช้คอมโพเนนต์ที่ไม่ใช่ directBootAware ในขณะที่ทำงานในโหมดบูตโดยตรง ซึ่งหมายความว่าไลบรารีใด ๆ ที่แอปใช้ซึ่งเรียกจากบริการจะต้องรับรู้การบูตโดยตรงหรือแอปจะต้องตรวจสอบว่าแอปทำงานในโหมดบูตโดยตรงหรือไม่และไม่เรียกใช้ในโหมดนั้น ตัวอย่างเช่น Firebase SDK ทำงานร่วมกับการบูตโดยตรง (สามารถรวมไว้ในแอปได้โดยไม่ขัดข้องในโหมดบูตโดยตรง) แต่ Firebase API จำนวนมากไม่รองรับการเรียกใช้ในโหมดบูตโดยตรง
- หากแอปกำลังใช้แอปพลิเคชันที่กำหนดเอง
Application
Application
จะต้องรับรู้การบูตโดยตรง (ไม่สามารถเข้าถึงที่เก็บข้อมูลที่มีการป้องกันข้อมูลประจำตัวในโหมดบูตโดยตรง)
สำหรับคำแนะนำในการส่งข้อความไปยังอุปกรณ์ในโหมดบูตโดยตรงโปรดดูที่ ส่งข้อความที่เปิดใช้งานการบูตโดยตรง