ตั้งค่าแอพไคลเอนต์ Firebase Cloud Messaging บน Android

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

ตั้งค่า SDK

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

แก้ไขรายการแอปของคุณ

เพิ่มรายการต่อไปนี้ในรายการแอปของคุณ:

  • บริการที่ขยาย FirebaseMessagingService นี่เป็นสิ่งจำเป็นหากคุณต้องการจัดการข้อความใด ๆ นอกเหนือจากการรับการแจ้งเตือนบนแอพในพื้นหลัง ในการรับการแจ้งเตือนในแอปเบื้องหน้า รับข้อมูลเพย์โหลด ส่งข้อความอัปสตรีม และอื่นๆ คุณต้องขยายบริการนี้
  • <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
  • (ไม่บังคับ) ภายในองค์ประกอบแอปพลิเคชัน องค์ประกอบข้อมูลเมตาเพื่อตั้งค่าไอคอนและสีการแจ้งเตือนเริ่มต้น Android จะใช้ค่าเหล่านี้เมื่อใดก็ตามที่ข้อความขาเข้าไม่ได้กำหนดไอคอนหรือสีไว้อย่างชัดเจน
  • <!-- 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 8.0 (API ระดับ 26) ขึ้นไป ช่องการแจ้งเตือน จะได้รับการสนับสนุนและแนะนำ FCM ให้ช่องการแจ้งเตือนเริ่มต้นพร้อมการตั้งค่าพื้นฐาน หากคุณต้องการ สร้าง และใช้แชนเนลเริ่มต้นของคุณเอง ให้ตั้งค่า default_notification_channel_id เป็น ID ของออบเจ็กต์ช่องทางการแจ้งเตือนของคุณดังที่แสดง FCM จะใช้ค่านี้เมื่อใดก็ตามที่ข้อความขาเข้าไม่ได้ตั้งค่าช่องทางการแจ้งเตือนอย่างชัดเจน หากต้องการเรียนรู้เพิ่มเติม โปรดดูที่ จัดการช่องทางการแจ้งเตือน
  • <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel_id" />

ขอสิทธิ์การแจ้งเตือนรันไทม์บน Android 13+

Android 13 แนะนำการอนุญาตรันไทม์ใหม่สำหรับการแสดงการแจ้งเตือน การดำเนินการนี้มีผลกับแอปทั้งหมดที่ทำงานบน Android 13 ขึ้นไปที่ใช้การแจ้งเตือน FCM

โดยค่าเริ่มต้น FCM SDK (เวอร์ชัน 23.0.6 หรือสูงกว่า) จะรวมสิทธิ์ POST_NOTIFICATIONS ที่กำหนดไว้ในรายการ อย่างไรก็ตาม แอปของคุณจะต้องร้องขอเวอร์ชันรันไทม์ของการอนุญาตนี้ผ่านค่าคงที่ android.permission.POST_NOTIFICATIONS แอปของคุณจะไม่ได้รับอนุญาตให้แสดงการแจ้งเตือนจนกว่าผู้ใช้จะอนุญาต

ในการขออนุญาตรันไทม์ใหม่:

Java

// Declare the launcher at the top of your Activity/Fragment:
private final ActivityResultLauncher<String> requestPermissionLauncher =
        registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
            if (isGranted) {
                // FCM SDK (and your app) can post notifications.
            } else {
                // TODO: Inform user that that your app will not show notifications.
            }
        });

// ...
private void askNotificationPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
            PackageManager.PERMISSION_GRANTED) {
        // FCM SDK (and your app) can post notifications.
    } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
        // TODO: display an educational UI explaining to the user the features that will be enabled
        //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
        //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
        //       If the user selects "No thanks," allow the user to continue without notifications.
    } else {
        // Directly ask for the permission
        requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
    }
}

Kotlin+KTX

// Declare the launcher at the top of your Activity/Fragment:
private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
    if (isGranted) {
        // FCM SDK (and your app) can post notifications.
    } else {
        // TODO: Inform user that that your app will not show notifications.
    }
}

// ...
private fun askNotificationPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
        PackageManager.PERMISSION_GRANTED
    ) {
        // FCM SDK (and your app) can post notifications.
    } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
        // TODO: display an educational UI explaining to the user the features that will be enabled
        //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
        //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
        //       If the user selects "No thanks," allow the user to continue without notifications.
    } else {
        // Directly ask for the permission
        requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
    }
}

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

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

สิทธิ์ในการแจ้งเตือนสำหรับแอปที่กำหนดเป้าหมายเป็น Android 12L (API ระดับ 32) หรือต่ำกว่า

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

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

ไม่บังคับ: ลบการอนุญาต POST_NOTIFICATIONS

โดยค่าเริ่มต้น FCM SDK จะรวมสิทธิ์ POST_NOTIFICATIONS หากแอปของคุณไม่ได้ใช้ข้อความแจ้งเตือน (ไม่ว่าจะผ่านการแจ้งเตือน FCM ผ่าน SDK อื่น หรือโพสต์โดยแอปของคุณโดยตรง) และคุณไม่ต้องการให้แอปของคุณรวมการอนุญาต คุณสามารถลบออกได้โดยใช้เครื่องหมาย remove ของการควบรวมกิจการ โปรดทราบว่าการลบการอนุญาตนี้จะป้องกันการแสดงการแจ้งเตือนทั้งหมด ไม่ใช่แค่การแจ้งเตือน FCM เพิ่มรายการต่อไปนี้ในไฟล์ Manifest ของแอปของคุณ:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" tools:node="remove"/>

เข้าถึงโทเค็นการลงทะเบียนอุปกรณ์

เมื่อเริ่มต้นแอปของคุณเป็นครั้งแรก FCM SDK จะสร้างโทเค็นการลงทะเบียนสำหรับอินสแตนซ์แอปไคลเอ็นต์ หากคุณต้องการกำหนดเป้าหมายอุปกรณ์เครื่องเดียวหรือสร้างกลุ่มอุปกรณ์ คุณจะต้องเข้าถึงโทเค็นนี้โดยขยาย FirebaseMessagingService และแทนที่ onNewToken

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

โทเค็นการลงทะเบียนอาจเปลี่ยนแปลงเมื่อ:

  • แอพถูกกู้คืนบนอุปกรณ์ใหม่
  • ผู้ใช้ถอนการติดตั้ง/ติดตั้งแอปอีกครั้ง
  • ผู้ใช้ล้างข้อมูลแอป

รับโทเค็นการลงทะเบียนปัจจุบัน

เมื่อคุณต้องการดึงโทเค็นปัจจุบัน ให้เรียก FirebaseMessaging.getInstance().getToken() :

Java

FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
          if (!task.isSuccessful()) {
            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
            return;
          }

          // Get new FCM registration token
          String token = task.getResult();

          // Log and toast
          String msg = getString(R.string.msg_token_fmt, token);
          Log.d(TAG, msg);
          Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    });

Kotlin+KTX

FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w(TAG, "Fetching FCM registration token failed", task.exception)
        return@OnCompleteListener
    }

    // Get new FCM registration token
    val token = task.result

    // Log and toast
    val msg = getString(R.string.msg_token_fmt, token)
    Log.d(TAG, msg)
    Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
})

ตรวจสอบการสร้างโทเค็น

การเรียกกลับ onNewToken ทุกครั้งที่มีการสร้างโทเค็นใหม่

Java

/**
 * There are two scenarios when onNewToken is called:
 * 1) When a new token is generated on initial app startup
 * 2) Whenever an existing token is changed
 * Under #2, there are three scenarios when the existing token is changed:
 * A) App is restored to a new device
 * B) User uninstalls/reinstalls the app
 * C) User clears app data
 */
@Override
public void onNewToken(@NonNull String token) {
    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
    // FCM registration token to your app server.
    sendRegistrationToServer(token);
}

Kotlin+KTX

/**
 * Called if the FCM registration token is updated. This may occur if the security of
 * the previous token had been compromised. Note that this is called when the
 * FCM registration 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
    // FCM registration token to your app server.
    sendRegistrationToServer(token)
}

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

ตรวจสอบบริการ Google Play

แอปที่ใช้ Play Services SDK ควรตรวจสอบอุปกรณ์เพื่อหา APK บริการ Google Play ที่เข้ากันได้ก่อนที่จะเข้าถึงคุณลักษณะบริการ Google Play ขอแนะนำให้ทำเช่นนี้ในสองแห่ง: ใน onCreate() ของกิจกรรมหลัก และใน onResume() การเช็คอิน onCreate() ช่วยให้มั่นใจได้ว่าแอปจะไม่สามารถใช้งานได้หากไม่มีการตรวจสอบสำเร็จ การเช็คอิน onResume() ช่วยให้มั่นใจได้ว่าหากผู้ใช้กลับมายังแอปที่ทำงานอยู่ด้วยวิธีการอื่น เช่น ผ่านปุ่มย้อนกลับ การตรวจสอบจะยังคงดำเนินการอยู่

หากอุปกรณ์ไม่มีบริการ Google Play เวอร์ชันที่เข้ากันได้ แอปของคุณสามารถเรียก GoogleApiAvailability.makeGooglePlayServicesAvailable() เพื่อให้ผู้ใช้ดาวน์โหลดบริการ Google Play จาก Play Store ได้

ป้องกันการเริ่มต้นอัตโนมัติ

เมื่อมีการสร้างโทเค็นการลงทะเบียน FCM ไลบรารีจะอัปโหลดตัวระบุและข้อมูลการกำหนดค่าไปยัง Firebase หากคุณต้องการป้องกันการสร้างโทเค็นอัตโนมัติ ให้ปิดใช้งานการรวบรวม Analytics และการเริ่มต้น FCM อัตโนมัติ (คุณต้องปิดใช้งานทั้งคู่) โดยเพิ่มค่าข้อมูลเมตาเหล่านี้ใน AndroidManifest.xml ของคุณ:

<meta-data
    android:name="firebase_messaging_auto_init_enabled"
    android:value="false" />
<meta-data
    android:name="firebase_analytics_collection_enabled"
    android:value="false" />

หากต้องการเปิดใช้งาน FCM auto-init อีกครั้ง ให้เรียกใช้รันไทม์:

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

Kotlin+KTX

Firebase.messaging.isAutoInitEnabled = true

หากต้องการเปิดใช้งานการรวบรวม Analytics อีกครั้ง ให้เรียก setAnalyticsCollectionEnabled() ของคลาส FirebaseAnalytics ตัวอย่างเช่น:

setAnalyticsCollectionEnabled(true);

ค่าเหล่านี้ยังคงอยู่ในการรีสตาร์ทแอปเมื่อตั้งค่าไว้

ขั้นตอนถัดไป

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

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

โปรดจำไว้ว่า เพื่อใช้ประโยชน์จากคุณลักษณะเหล่านี้ คุณจะต้อง ใช้งานเซิร์ฟเวอร์ และโปรโตคอลเซิร์ฟเวอร์ (HTTP หรือ XMPP) หรือใช้งาน Admin SDK