了解 2023 年 Google I/O 大会上介绍的 Firebase 亮点。了解详情

รับข้อความในแอป Android

การแจ้งเตือนของ Firebase ทำงานแตกต่างกันไปขึ้นอยู่กับสถานะเบื้องหน้า/เบื้องหลังของแอปที่รับ หากคุณต้องการให้แอปเบื้องหน้าได้รับข้อความแจ้งเตือนหรือข้อความข้อมูล คุณจะต้องเขียนโค้ดเพื่อจัดการกับการเรียกกลับ onMessageReceived สำหรับคำอธิบายความแตกต่างระหว่างข้อความแจ้งเตือนและข้อมูล โปรดดู ที่ ประเภทข้อความ

การจัดการข้อความ

หากต้องการรับข้อความ ให้ใช้บริการที่ขยาย FirebaseMessagingService บริการของคุณควรแทนที่การเรียกกลับ onMessageReceived และ onDeletedMessages ควรจัดการข้อความใด ๆ ภายใน 20 วินาทีหลังจากได้รับ (10 วินาทีสำหรับ Android Marshmallow) กรอบเวลาอาจสั้นลงขึ้นอยู่กับความล่าช้าของระบบปฏิบัติการที่เกิดขึ้นก่อนการโทร onMessageReceived หลังจากเวลาดังกล่าว ลักษณะการทำงานต่างๆ ของระบบปฏิบัติการ เช่น ขีดจำกัดการดำเนินการในเบื้องหลัง ของ Android O อาจขัดขวางความสามารถของคุณในการทำงานให้เสร็จ สำหรับข้อมูลเพิ่มเติม โปรดดูภาพรวมของเราเกี่ยวกับ ลำดับความสำคัญของข้อความ

onMessageReceived มีให้สำหรับประเภทข้อความส่วนใหญ่ โดยมีข้อยกเว้นต่อไปนี้:

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

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

สรุป:

สถานะแอป การแจ้งเตือน ข้อมูล ทั้งคู่
เบื้องหน้า onMessageReceived onMessageReceived 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 ใช้สีเริ่มต้นที่กำหนดเองสำหรับ

  • ข้อความแจ้งเตือนทั้งหมดที่ส่งจาก ผู้จัดทำการแจ้งเตือน
  • ข้อความแจ้งเตือนใด ๆ ที่ไม่ได้กำหนดสีอย่างชัดเจนในเพย์โหลดการแจ้งเตือน

หากไม่มีการตั้งค่าไอคอนเริ่มต้นที่กำหนดเองและไม่มีการตั้งค่าไอคอนในเพย์โหลดการแจ้งเตือน Android จะแสดงไอคอนแอปพลิเคชันที่แสดงเป็นสีขาว

แทนที่ onMessageReceived

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

Kotlin+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}")

        // 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.
}

แทนที่ onDeletedMessages

ในบางสถานการณ์ FCM อาจไม่ส่งข้อความ กรณีนี้เกิดขึ้นเมื่อมีข้อความมากเกินไป (>100) ที่รอดำเนินการสำหรับแอปของคุณบนอุปกรณ์ใดอุปกรณ์หนึ่ง ณ เวลาที่เชื่อมต่อ หรือหากอุปกรณ์ไม่ได้เชื่อมต่อกับ FCM นานกว่าหนึ่งเดือน ในกรณีเหล่านี้ คุณอาจได้รับการติดต่อกลับไปยัง FirebaseMessagingService.onDeletedMessages() เมื่ออินสแตนซ์ของแอปได้รับการเรียกกลับนี้ อินสแตนซ์ควรทำการซิงค์อย่างสมบูรณ์กับเซิร์ฟเวอร์แอปของคุณ หากคุณไม่ได้ส่งข้อความไปยังแอปบนอุปกรณ์นั้นภายใน 4 สัปดาห์ที่ผ่านมา FCM จะไม่เรียกใช้ onDeletedMessages()

จัดการข้อความแจ้งเตือนในแอปเบื้องหลัง

เมื่อแอปของคุณอยู่ในพื้นหลัง Android จะส่งข้อความแจ้งเตือนไปที่ซิสเต็มเทรย์ ผู้ใช้แตะที่การแจ้งเตือนจะเปิดตัวเรียกใช้งานแอปตามค่าเริ่มต้น

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

สำหรับข้อมูลเชิงลึกเกี่ยวกับการส่งข้อความไปยังแอปของคุณ โปรดดูแด ชบอร์ดการรายงาน FCM ซึ่งบันทึกจำนวนข้อความที่ส่งและเปิดบนอุปกรณ์ Apple และ Android พร้อมด้วยข้อมูลสำหรับ "การแสดงผล" (การแจ้งเตือนที่ผู้ใช้เห็น) สำหรับแอป Android

รับข้อความ FCM ในโหมดบูตโดยตรง

นักพัฒนาที่ต้องการส่งข้อความ FCM ไปยังแอพก่อนที่อุปกรณ์จะปลดล็อคสามารถเปิดใช้งานแอพ Android เพื่อรับข้อความเมื่ออุปกรณ์อยู่ในโหมดบูตโดยตรง ตัวอย่างเช่น คุณอาจต้องการให้ผู้ใช้แอปของคุณได้รับการแจ้งเตือนแม้ในอุปกรณ์ที่ล็อคอยู่

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

ข้อกำหนดเบื้องต้น

  • ต้องตั้งค่าอุปกรณ์สำหรับโหมดบูตโดยตรง
  • อุปกรณ์ต้องติดตั้งบริการ Google Play เวอร์ชันล่าสุด (19.0.54 หรือใหม่กว่า)
  • แอปต้องใช้ FCM SDK ( com.google.firebase:firebase-messaging ) เพื่อรับข้อความ FCM

เปิดใช้งานการจัดการข้อความในโหมดบูตโดยตรงในแอปของคุณ

  1. ในไฟล์ Gradle ระดับแอป ให้เพิ่มการอ้างอิงในไลบรารีสนับสนุนการบูตโดยตรงของ FCM:

    implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
    
  2. ทำให้ทราบการบูตโดยตรงของ FirebaseMessagingService ของแอปโดยเพิ่มแอตทริบิวต์ android:directBootAware="true" ในรายการแอป:

    <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false"
        android:directBootAware="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    

สิ่งสำคัญคือต้องแน่ใจว่า FirebaseMessagingService นี้สามารถทำงานในโหมดบูตโดยตรงได้ ตรวจสอบข้อกำหนดต่อไปนี้:

  • บริการไม่ควรเข้าถึงที่เก็บข้อมูลที่มีการป้องกันข้อมูลรับรองขณะทำงานในโหมดบูตโดยตรง
  • บริการไม่ควรพยายามใช้คอมโพเนนต์ เช่น Activities , BroadcastReceivers หรือ Services อื่นๆ ที่ไม่ได้ทำเครื่องหมายว่ารับรู้การบูตโดยตรงขณะทำงานในโหมดการบูตโดยตรง
  • ไลบรารีใดๆ ที่ใช้บริการจะต้องไม่เข้าถึงที่เก็บข้อมูลที่มีการป้องกันด้วยข้อมูลรับรอง หรือเรียกคอมโพเนนต์ที่ไม่ใช่ directBootAware ในขณะที่ทำงานในโหมดบูตโดยตรง ซึ่งหมายความว่าไลบรารีใดๆ ที่แอปใช้ซึ่งเรียกจากบริการจะต้องได้รับการรับรู้การบูตโดยตรง หรือแอปจะต้องตรวจสอบว่ากำลังทำงานในโหมดการบูตโดยตรงหรือไม่ และไม่เรียกใช้ในโหมดนั้น ตัวอย่างเช่น Firebase SDK ทำงานร่วมกับการบู๊ตโดยตรง (สามารถรวมไว้ในแอปโดยไม่ขัดข้องในโหมดการบู๊ตโดยตรง) แต่ Firebase API จำนวนมากไม่รองรับการเรียกในโหมดการบู๊ตโดยตรง
  • หากแอปกำลังใช้ Application ที่กำหนดเอง Application พลิเคชันจะต้องรับรู้การบู๊ตโดยตรงด้วย (ไม่สามารถเข้าถึงที่เก็บข้อมูลที่ได้รับการป้องกันข้อมูลรับรองในโหมดการบู๊ตโดยตรง)

สำหรับคำแนะนำในการส่งข้อความไปยังอุปกรณ์ในโหมดการบูตโดยตรง โปรดดู ที่ ส่งข้อความที่เปิดใช้งานการบูตโดยตรง