Advanced Android in Kotlin 01.2: Android Firebase Cloud Messaging

Codelab นี้เป็นส่วนหนึ่งของหลักสูตร Android ขั้นสูงใน Kotlin คุณจะได้รับประโยชน์สูงสุดจากหลักสูตรนี้หากทำตาม Codelab ตามลำดับ แต่ไม่จำเป็นต้องทำ Codelab ของหลักสูตรทั้งหมดแสดงอยู่ในหน้า Landing Page ของ Codelab Android ขั้นสูงใน Kotlin

บทนำ

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

ข้อความ Push คืออะไร

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

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

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

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

Firebase Cloud Messaging คืออะไร

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

นอกจากนี้ คุณยังใช้ Firebase Cloud Messaging เพื่อโอนข้อมูลจากแอปแบ็กเอนด์หรือจากโปรเจ็กต์ Firebase ไปยังผู้ใช้ได้ด้วย

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีใช้ Firebase Cloud Messaging เพื่อส่งการแจ้งเตือนแบบพุชสำหรับแอป Android รวมถึงส่งข้อมูล

หากพบปัญหา (ข้อบกพร่องของโค้ด ข้อผิดพลาดทางไวยากรณ์ คำที่ไม่ชัดเจน ฯลฯ) ขณะทำตาม Codelab นี้ โปรดรายงานปัญหาผ่านลิงก์รายงานข้อผิดพลาดที่มุมซ้ายล่างของ Codelab

สิ่งที่คุณควรทราบอยู่แล้ว

คุณควรคุ้นเคยกับสิ่งต่อไปนี้

  • วิธีสร้างแอป Android ใน Kotlin โดยเฉพาะอย่างยิ่ง ให้ทำงานกับ Android SDK
  • วิธีออกแบบแอปโดยใช้คอมโพเนนต์สถาปัตยกรรมและการเชื่อมโยงข้อมูล
  • ความเข้าใจพื้นฐานเกี่ยวกับ Broadcast Receiver
  • มีความเข้าใจพื้นฐานเกี่ยวกับ AlarmManager
  • วิธีสร้างและส่งการแจ้งเตือนโดยใช้ NotificationManager

สิ่งที่คุณจะได้เรียนรู้

  • วิธีพุชข้อความไปยังผู้ใช้ผ่าน Firebase Cloud Messaging
  • วิธีส่งข้อมูลจากแบ็กเอนด์ไปยังแอปโดยใช้ข้อความข้อมูล ซึ่งเป็นส่วนหนึ่งของ Firebase Cloud Messaging

สิ่งที่คุณต้องดำเนินการ

  • เพิ่มการแจ้งเตือนแบบพุชลงในแอปเริ่มต้น
  • จัดการ Firebase Cloud Messaging ขณะที่แอปทํางานอยู่
  • โอนข้อมูลด้วย Firebase Cloud Messaging

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

หากต้องการรับแอปตัวอย่าง คุณสามารถเลือกทำอย่างใดอย่างหนึ่งต่อไปนี้

โคลนที่เก็บจาก GitHub แล้วเปลี่ยนไปที่สาขา starter โดยทำดังนี้

$  git clone https://github.com/googlecodelabs/android-kotlin-notifications-fcm


หรือคุณจะดาวน์โหลดที่เก็บเป็นไฟล์ Zip, แตกไฟล์ และเปิดใน Android Studio ก็ได้

ดาวน์โหลด Zip

ขั้นตอนที่ 1: สร้างโปรเจ็กต์ Firebase

ก่อนที่จะเพิ่ม Firebase ลงในแอป Android ได้ คุณต้องสร้างโปรเจ็กต์ Firebase เพื่อเชื่อมต่อกับแอป Android

  1. เข้าสู่ระบบคอนโซล Firebase
  2. คลิกเพิ่มโปรเจ็กต์ จากนั้นเลือกหรือป้อนชื่อโปรเจ็กต์ ตั้งชื่อโปรเจ็กต์ว่า fcm-codelab
  3. คลิกต่อไป
  4. คุณข้ามการตั้งค่า Google Analytics ได้โดยปิดปุ่มเปิดใช้ Google Analytics สำหรับโปรเจ็กต์นี้
  5. คลิกสร้างโปรเจ็กต์เพื่อตั้งค่าโปรเจ็กต์ Firebase ให้เสร็จ

ขั้นตอนที่ 2: ลงทะเบียนแอปกับ Firebase

ตอนนี้คุณมีโปรเจ็กต์ Firebase แล้ว คุณจึงเพิ่มแอป Android ลงในโปรเจ็กต์ได้

  1. ที่กึ่งกลางหน้าภาพรวมโปรเจ็กต์ของคอนโซล Firebase ให้คลิกไอคอน Android เพื่อเปิดเวิร์กโฟลว์การตั้งค่า

  1. ป้อน com.example.android.eggtimernotifications ในช่องชื่อแพ็กเกจ Android
  2. คลิกลงทะเบียนแอป

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

ขั้นตอนที่ 3: เพิ่มไฟล์การกำหนดค่า Firebase ลงในโปรเจ็กต์

เพิ่มไฟล์การกำหนดค่า Firebase สำหรับ Android ลงในแอป

  1. คลิกดาวน์โหลด google-services.json เพื่อรับไฟล์การกำหนดค่า Firebase Android (google-services.json) ตรวจสอบว่าไฟล์การกำหนดค่าไม่มีอักขระเพิ่มเติมต่อท้ายและมีชื่อว่า google-services.json อย่างถูกต้อง
  2. ย้ายไฟล์การกำหนดค่าไปยังไดเรกทอรีโมดูล (ระดับแอป) ของแอป

ขั้นตอนที่ 4: กำหนดค่าโปรเจ็กต์ Android เพื่อเปิดใช้ผลิตภัณฑ์ Firebase

หากต้องการเปิดใช้ผลิตภัณฑ์ Firebase ในแอป คุณต้องเพิ่มปลั๊กอิน google-services ลงในไฟล์ Gradle

  1. ในไฟล์ Gradle ระดับรูท (ระดับโปรเจ็กต์) (build.gradle) ให้ตรวจสอบว่าคุณมีที่เก็บ Maven ของ Google
  2. จากนั้นเพิ่มกฎเพื่อรวมปลั๊กอินบริการของ Google

build.gradle

buildscript {

  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
  }

  dependencies {
    // ...

    // Add the following line:
    classpath 'com.google.gms:google-services:4.3.2'  // Google Services plugin
  }
}

allprojects {
  // ...

  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
    // ...
  }
}
  1. ในไฟล์ Gradle ระดับโมดูล (ระดับแอป) (โดยปกติคือ app/build.gradle) ให้เพิ่มบรรทัดเพื่อใช้ปลั๊กอินที่ด้านล่างของไฟล์

app/build.gradle

apply plugin: 'com.android.application'

android {
  // ...
}

// Add the following line to the bottom of the file:
apply plugin: 'com.google.gms.google-services'  // Google Play services Gradle plugin

ในงานนี้ คุณจะเพิ่ม Firebase Cloud Messaging (FCM) ลงในโปรเจ็กต์เพื่อใช้การแจ้งเตือนแบบพุช

รหัสบริการ Android สำหรับ FCM ของ Codelab นี้ระบุไว้ใน MyFirebaseMessagingService.kt ในขั้นตอนต่อไปนี้ คุณจะเพิ่มโค้ดลงในแอป Android

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

  1. เปิด MyFirebaseMessagingService.kt
  2. ตรวจสอบไฟล์และฟังก์ชันต่อไปนี้โดยเฉพาะ
  • onNewToken()—เรียกใช้โดยอัตโนมัติหากลงทะเบียนบริการไว้ในไฟล์ Manifest ของ Android ฟังก์ชันนี้จะเรียกใช้เมื่อคุณเรียกใช้แอปเป็นครั้งแรก และทุกครั้งที่ Firebase ออกโทเค็นใหม่สำหรับแอปของคุณ โทเค็นคือคีย์การเข้าถึงโปรเจ็กต์แบ็กเอนด์ Firebase โดยระบบจะสร้างขึ้นสำหรับอุปกรณ์ไคลเอ็นต์ของคุณโดยเฉพาะ โทเค็นนี้ช่วยให้ Firebase ทราบว่าแบ็กเอนด์ควรส่งข้อความไปยังไคลเอ็นต์ใด นอกจากนี้ Firebase ยังทราบด้วยว่าไคลเอ็นต์นี้ถูกต้องและมีสิทธิ์เข้าถึงโปรเจ็กต์ Firebase นี้หรือไม่
  • onMessageReceived - เรียกใช้เมื่อแอปทำงานและ Firebase ส่งข้อความไปยังแอป ฟังก์ชันนี้จะได้รับออบเจ็กต์ RemoteMessage ซึ่งสามารถพกพาการแจ้งเตือนหรือเพย์โหลดข้อความข้อมูลได้ คุณจะได้ดูข้อมูลเพิ่มเติมเกี่ยวกับความแตกต่างระหว่างการแจ้งเตือนและเพย์โหลดข้อความข้อมูลใน Codelab นี้

ขั้นตอนที่ 1: ส่งการแจ้งเตือน FCM ไปยังอุปกรณ์เครื่องเดียว

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

เมื่อแบ็กเอนด์ของ Firebase สร้างโทเค็นใหม่หรือรีเฟรชโทเค็น ระบบจะเรียกใช้ฟังก์ชัน onNewToken() โดยส่งโทเค็นใหม่เป็นอาร์กิวเมนต์ หากต้องการกำหนดเป้าหมายอุปกรณ์เครื่องเดียวหรือสร้างกลุ่มอุปกรณ์ที่ต้องการส่งข้อความออกอากาศ คุณจะต้องเข้าถึงโทเค็นนี้โดยการขยาย FirebaseMessagingService และลบล้าง onNewToken()

  1. เปิด AndroidManifest.xml และยกเลิกการแสดงความคิดเห็นในโค้ดต่อไปนี้เพื่อเปิดใช้ MyFirebaseMessagingService สำหรับแอปจับเวลาไข่ ข้อมูลเมตาของบริการในไฟล์ AndroidManifest จะลงทะเบียน MyFirebaseMessagingService เป็นบริการและเพิ่มตัวกรอง Intent เพื่อให้บริการนี้รับข้อความที่ส่งจาก FCM ได้ ส่วนสุดท้ายของข้อมูลเมตาจะประกาศ breakfast_notification_channel_id เป็น default_notification_channel_id สำหรับ Firebase คุณจะต้องใช้รหัสนี้ในขั้นตอนถัดไป
<!-- AndroidManifest.xml -->
<!-- TODO: Step 3.0 uncomment to start the service  -->

        <service
                android:name=".MyFirebaseMessagingService"
                android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>
        <!-- [START fcm_default_icon] -->
        <!--
 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/common_google_signin_btn_icon_dark"/>
        <!--
 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"/> <!-- [END fcm_default_icon] -->
        <!-- [START fcm_default_channel] -->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="@string/breakfast_notification_channel_id" />
        <!-- [END fcm_default_channel] -->

คุณควรสร้างช่องทางการแจ้งเตือนใหม่สำหรับ FCM เนื่องจากผู้ใช้อาจต้องการเปิด/ปิดใช้การแจ้งเตือนแบบพุชของนาฬิกาจับเวลาหรือ FCM แยกกัน

  1. เปิด ui/EggTimerFragment.kt ใน onCreateView() ให้เพิ่มโค้ดการสร้างช่องต่อไปนี้
// EggTimerFragment.kt

   // TODO: Step 3.1 create a new channel for FCM
    createChannel(
        getString(R.string.breakfast_notification_channel_id),
        getString(R.string.breakfast_notification_channel_name)
    )
  1. เปิด MyFirebaseMessagingService.kt แล้วยกเลิกการแสดงความคิดเห็นในฟังก์ชัน onNewToken() ระบบจะเรียกใช้ฟังก์ชันนี้เมื่อสร้างโทเค็นใหม่
// MyFirebaseMessagingService.kt

   // TODO: Step 3.2 log registration token
    // [START on_new_token]
    /**
     * Called if InstanceID token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the     
     * InstanceID token is initially generated so this is where you would retrieve     
     * the token.
     */
    override fun onNewToken(token: String?) {
        Log.d(TAG, "Refreshed token: $token")

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        // Instance ID token to your app server.
        sendRegistrationToServer(token)
    }
    // [END on_new_token]
  1. เรียกใช้แอปตัวจับเวลา
  2. สังเกต logcat (ดู > หน้าต่างเครื่องมือ > Logcat) คุณควรเห็นบรรทัดบันทึกที่แสดงโทเค็นของคุณคล้ายกับบรรทัดด้านล่าง นี่คือโทเค็นที่คุณต้องใช้เพื่อส่งข้อความไปยังอุปกรณ์นี้ ระบบจะเรียกใช้ฟังก์ชันนี้เมื่อสร้างโทเค็นใหม่เท่านั้น
2019-07-23 13:09:15.243 2312-2459/com.example.android.eggtimernotifications D/MyFirebaseMsgService: Refreshed token: f2esflBoQbI:APA91bFMzNNFaIskjr6KIV4zKjnPA4hxekmrtbrtba2aDbh593WQnm11ed54Mv6MZ9Yeerver7pzgwfKx7R9BHFffLBItLEgPvrtF0TtX9ToCrXZ5y7Hd-m

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

ตอนนี้คุณทดสอบได้โดยส่งการแจ้งเตือน หากต้องการส่งการแจ้งเตือน คุณจะต้องใช้เครื่องมือแต่งการแจ้งเตือน

  1. เปิดคอนโซล Firebase แล้วเลือกโปรเจ็กต์
  2. จากนั้นเลือก Cloud Messaging จากการนำทางทางด้านซ้าย
  3. คลิกส่งข้อความแรก

  1. ป้อน Time for Breakfast! เป็นชื่อการแจ้งเตือนและ Don't forget to eat eggs! เป็นข้อความการแจ้งเตือน แล้วเลือกส่งข้อความทดสอบ กล่องโต้ตอบป๊อปอัปทดสอบในอุปกรณ์จะปรากฏขึ้น โดยขอให้คุณระบุโทเค็นการลงทะเบียน FCM

  1. คัดลอกโทเค็นแอปจาก Logcat

  1. วางโทเค็นนี้ลงในช่องเพิ่มโทเค็นการลงทะเบียน FCM ภายในหน้าต่างป๊อปอัป จากนั้นคลิกปุ่มเพิ่มข้างโทเค็น
  2. เลือกโทเค็นในรายการช่องทําเครื่องหมายที่ปรากฏ ปุ่มทดสอบควรเปิดใช้ได้

  1. เปิดแอปจับเวลาไข่ในเบื้องหลัง บนอุปกรณ์
  2. คลิกทดสอบในป๊อปอัป
  1. หลังจากคลิกทดสอบแล้ว อุปกรณ์ไคลเอ็นต์เป้าหมายที่เรียกใช้แอปของคุณในเบื้องหลังควรได้รับการแจ้งเตือนในถาดการแจ้งเตือนของระบบ (คุณจะเห็นข้อมูลเพิ่มเติมเกี่ยวกับวิธีจัดการข้อความ FCM เมื่อแอปอยู่ในเบื้องหน้าในภายหลัง)

งาน: ส่งการแจ้งเตือน FCM ไปยังหัวข้อ

การรับส่งข้อความตามหัวข้อของ FCM อิงตามรูปแบบการเผยแพร่/การสมัครรับข้อมูล

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

หัวข้อช่วยให้คุณส่งข้อความไปยังอุปกรณ์หลายเครื่องที่เลือกใช้หัวข้อนั้นๆ ได้ สำหรับไคลเอ็นต์ หัวข้อคือแหล่งข้อมูลที่เฉพาะเจาะจงซึ่งไคลเอ็นต์สนใจ สำหรับเซิร์ฟเวอร์ หัวข้อคือกลุ่มของอุปกรณ์ที่เลือกรับข้อมูลอัปเดตเกี่ยวกับแหล่งข้อมูลที่เฉพาะเจาะจง หัวข้อสามารถใช้เพื่อนำเสนอหมวดหมู่ของการแจ้งเตือน เช่น ข่าว พยากรณ์อากาศ และผลการแข่งขันกีฬา สำหรับส่วนนี้ของ Codelab คุณจะสร้างหัวข้อ "อาหารเช้า" เพื่อเตือนผู้ใช้แอปที่สนใจให้กินไข่กับอาหารเช้า

หากต้องการสมัครรับข้อมูลหัวข้อ แอปไคลเอ็นต์จะเรียกฟังก์ชัน subscribeToTopic() ของ Firebase Cloud Messaging พร้อมชื่อหัวข้อ breakfast การโทรนี้อาจมีผลลัพธ์ 2 อย่าง หากผู้โทรสำเร็จ ระบบจะเรียกใช้OnCompleteListener Callback พร้อมข้อความที่สมัครใช้บริการ หากไคลเอ็นต์สมัครใช้บริการไม่สำเร็จ การเรียกกลับจะได้รับข้อความแสดงข้อผิดพลาดแทน

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

  1. เปิด EggTimerFragment.kt แล้วค้นหาฟังก์ชัน subscribeTopic() ที่ว่างเปล่า
  2. รับอินสแตนซ์ของ FirebaseMessaging และเรียกใช้ฟังก์ชัน subscibeToTopic() ด้วยชื่อหัวข้อ
  3. เพิ่ม addOnCompleteListener เพื่อรับการแจ้งเตือนจาก FCM ว่าการสมัครใช้บริการสำเร็จหรือไม่
// EggTimerFragment.kt

   // TODO: Step 3.3 subscribe to breakfast topic
    private fun subscribeTopic() {
        // [START subscribe_topics]
        FirebaseMessaging.getInstance().subscribeToTopic(TOPIC)
            .addOnCompleteListener { task ->
                var msg = getString(R.string.message_subscribed)
                if (!task.isSuccessful) {
                    msg = getString(R.string.message_subscribe_failed)
                }
                Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
            }
        // [END subscribe_topics]
    }
  1. เรียกใช้ฟังก์ชัน subscribeTopic() เพื่อติดตามหัวข้อเมื่อแอปเริ่มต้น เลื่อนขึ้นไปที่ onCreateView() แล้วเพิ่มการโทรไปยัง subscribeTopic()
// EggTimerFragment.kt

   // TODO: Step 3.4 call subscribe topics on start
    subscribeTopic()

    return binding.root
  1. หากต้องการติดตามหัวข้ออาหารเช้า ให้เรียกใช้แอปอีกครั้ง คุณควรเห็นข้อความป๊อปอัปที่ระบุว่า "ติดตามหัวข้อแล้ว"

ตอนนี้คุณทดสอบการส่งข้อความไปยังหัวข้อได้แล้ว โดยทำดังนี้

  1. เปิดเครื่องมือแต่งการแจ้งเตือน แล้วเลือกแต่งการแจ้งเตือน
  2. ตั้งค่าชื่อการแจ้งเตือนและข้อความการแจ้งเตือนเช่นเดิม
  3. คราวนี้แทนที่จะส่งข้อความไปยังอุปกรณ์เครื่องเดียว ให้คลิกหัวข้อในส่วนเป้าหมาย แล้วป้อน breakfast เป็นหัวข้อของข้อความ

  1. เลือกตอนนี้เพื่อกำหนดเวลา

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

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

เมื่อใช้การแจ้งเตือน โปรดคำนึงถึงเสมอว่าผู้ใช้สามารถปิดช่องทางการแจ้งเตือนได้ทุกเมื่อ

ขั้นตอนที่ 1: ข้อความข้อมูล

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

หากต้องการจัดการข้อความข้อมูล คุณต้องจัดการเพย์โหลดข้อมูลในฟังก์ชัน onMessageReceived() ของ MyFirebaseMessagingService ระบบจะจัดเก็บเพย์โหลดไว้ในพร็อพเพอร์ตี้ data ของออบเจ็กต์ remoteMessage ทั้งออบเจ็กต์ remoteMessage และพร็อพเพอร์ตี้ data สามารถเป็น null ได้

  1. เปิด MyFirebaseMessagingService.
  2. ตรวจสอบว่าdataพร็อพเพอร์ตี้ของออบเจ็กต์ remoteMessage มีค่าหรือไม่ และพิมพ์ข้อมูลลงในบันทึก
// MyFirebaseMessagingService.kt

    // [START receive_message]
    override fun onMessageReceived(remoteMessage: RemoteMessage?) {
        // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
        Log.d(TAG, "From: ${remoteMessage?.from}")
        
       // TODO: Step 3.5 check messages for data
        // Check if the message contains a data payload.
        remoteMessage?.data?.let {
            Log.d(TAG, "Message data payload: " + remoteMessage.data)
        }

    }
    // [END receive_message]

หากต้องการทดสอบโค้ด คุณสามารถใช้เครื่องมือแต่งการแจ้งเตือนอีกครั้งได้

  1. เปิดเครื่องมือแต่งข้อความแจ้ง สร้างข้อความใหม่ และตั้งค่าเป้าหมาย เป็นหัวข้อ "อาหารเช้า"
  2. คราวนี้เมื่อไปถึงขั้นตอนที่ 4 ตัวเลือกเพิ่มเติม ให้ตั้งค่าพร็อพเพอร์ตี้คีย์และค่าข้อมูลที่กำหนดเองดังนี้
  1. คีย์: eggs
  2. ค่า: 3

  1. ตรวจสอบว่าแอปทำงานในเบื้องหน้า หากแอปอยู่เบื้องหลัง ข้อความ FCM จะทริกเกอร์การแจ้งเตือนอัตโนมัติ และฟังก์ชัน onMessageReceived() จะได้รับเฉพาะออบเจ็กต์ remoteMessage เมื่อผู้ใช้คลิกการแจ้งเตือน
  2. ส่งข้อความจากเครื่องมือแต่งการแจ้งเตือน และสังเกตบันทึกข้อความข้อมูลที่ปรากฏใน Logcat

ขั้นตอนที่ 2: การจัดการข้อความในเบื้องหน้าและเบื้องหลัง

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

  • หากแอปทํางานในเบื้องหลังและข้อความมีเพย์โหลดการแจ้งเตือน ระบบจะแสดงการแจ้งเตือนในถาดการแจ้งเตือนโดยอัตโนมัติ หากข้อความมีเพย์โหลดข้อมูลด้วย แอปจะจัดการเพย์โหลดข้อมูลเมื่อผู้ใช้แตะการแจ้งเตือน
  • หากแอปทำงานอยู่เบื้องหน้าและหากการแจ้งเตือนข้อความมีเพย์โหลดการแจ้งเตือน การแจ้งเตือนจะไม่ปรากฏโดยอัตโนมัติ แอปต้องตัดสินใจว่าจะจัดการการแจ้งเตือนในonMessageReceived()ฟังก์ชันอย่างไร หากข้อความมีเพย์โหลดข้อมูลด้วย แอปจะเป็นผู้จัดการเพย์โหลดทั้ง 2 รายการ

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

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

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

  1. เปิดฟังก์ชัน onMessageReceived() ใน MyFirebaseMessagingService อีกครั้ง
  2. หลังจากโค้ดที่คุณเพิ่งเพิ่มเพื่อตรวจสอบข้อความข้อมูล ให้เพิ่มโค้ดต่อไปนี้ซึ่งจะส่งการแจ้งเตือนโดยใช้เฟรมเวิร์กการแจ้งเตือน
// MyFirebaseMessagingService.kt

    // TODO: Step 3.6 check messages for notification and call sendNotification
    // Check if the message contains a notification payload.
    remoteMessage.notification?.let {
        Log.d(TAG, "Message Notification Body: ${it.body}")
        sendNotification(it.body as String)
    }
  1. หากเรียกใช้แอปอีกครั้งและส่งการแจ้งเตือนโดยใช้เครื่องมือแต่งการแจ้งเตือน คุณควรเห็นการแจ้งเตือนเหมือนกับที่เคยเห็นในส่วนแรกของโค้ดแล็บ ไม่ว่าแอปจะอยู่ในเบื้องหน้าหรือเบื้องหลังก็ตาม

โค้ดโซลูชันอยู่ในสาขาหลักของโค้ดที่คุณดาวน์โหลด

  • ติดตั้งใช้งาน FCM BroadcastReceiver โดยขยาย FirebaseMessagingService
  • ตั้งค่าโปรเจ็กต์ Firebase Cloud Messaging (FCM) และเพิ่ม FCM ลงในแอป Android
  • ทดสอบแอปโดยส่งข้อความ Push จากเครื่องมือแต่งการแจ้งเตือน
  • สมัครรับข้อมูลหัวข้อ FCM โดยเรียกใช้ฟังก์ชัน subscribeToTopic() ของคลาส FirebaseMessaging
  • ส่งเพย์โหลดข้อมูลโดยใช้ออบเจ็กต์ RemoteMessage
  • จัดการข้อมูลในฟังก์ชัน onMessageReceived()
  • เพิ่มตรรกะเพื่อจัดการ FCM เมื่อแอปอยู่เบื้องหน้าและเมื่อแอปอยู่เบื้องหลัง

หลักสูตร Udacity:

เอกสารประกอบของ Firebase

ดูลิงก์ไปยัง Codelab อื่นๆ ในหลักสูตรนี้ได้ที่หน้า Landing Page ของ Codelab Android ขั้นสูงใน Kotlin