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

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

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

ในการรับข้อความ โปรดใช้บริการแบบขยาย FirebaseMessagingService บริการของคุณควรลบล้าง onMessageReceived และ onDeletedMessages Callback

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

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

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

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

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

สถานะของแอป การแจ้งเตือน ข้อมูล ทั้งสอง
พื้นหน้า 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 คุณสามารถดำเนินการตาม ข้อความระยะไกล และรับข้อมูลข้อความ:

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

จัดการข้อความแจ้งเตือนในแอปที่ทำงานอยู่เบื้องหลัง

เมื่อแอปอยู่ในเบื้องหลัง Android จะส่งข้อความการแจ้งเตือนไปยัง ถาดระบบ ผู้ใช้แตะการแจ้งเตือนดังกล่าวจะเปิดตัวเปิดแอปด้วย "ค่าเริ่มต้น"

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

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

รับข้อความ FCM ในโหมดการเปิดเครื่องโดยตรง

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

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

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

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

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

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

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

    <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 จะต้องเปิดเครื่องโดยตรงด้วย ทราบ (ไม่มีสิทธิ์เข้าถึงที่จัดเก็บข้อมูลรับรองในโหมดเปิดเครื่องโดยตรง)

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