Catch up on everthing we announced at this year's Firebase Summit. Learn more

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

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

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

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

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

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

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

สรุป:

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

แก้ไขรายการแอป

หากต้องการใช้ 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 วัตถุและได้รับข้อมูลที่เป็นข้อความ:

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

แอปที่จำกัดในเบื้องหลัง (Android P หรือใหม่กว่า)

FCM อาจไม่ส่งข้อความไปยังปพลิเคชันที่ถูกใส่ลงไปใน ข้อ จำกัด พื้นหลัง โดยผู้ใช้ (เช่นผ่าน: Setting -> ปพลิเคชันและประกาศ -> [APPNAME] -> Battery) เมื่อแอปของคุณถูกลบออกจากการจำกัดพื้นหลังแล้ว ข้อความใหม่ไปยังแอปจะถูกส่งเหมือนเดิม เพื่อที่จะป้องกันไม่ให้ข้อความหายไปและส่งผลกระทบต่อข้อ จำกัด พื้นฐานอื่น ๆ ให้แน่ใจว่าจะหลีกเลี่ยงพฤติกรรมที่ไม่ดีโดยระบุ Android ตับ ความพยายาม ลักษณะการทำงานเหล่านี้อาจทำให้อุปกรณ์ Android แนะนำให้ผู้ใช้ทราบว่าแอปของคุณถูกจำกัดการทำงานในเบื้องหลัง แอปของคุณสามารถตรวจสอบหากมีการใช้พื้นหลัง จำกัด : isBackgroundRestricted ()

รับข้อความ 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" แอตทริบิวต์ในประจักษ์ app:

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

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