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

FCM ต้องใช้อุปกรณ์ที่ใช้ Android 5.0 ขึ้นไปที่ติดตั้งแอป Google Play Store ด้วย หรือโปรแกรมจำลองที่ใช้ Android 5.0 ที่มี Google APIs โปรดทราบว่าคุณไม่ได้จำกัดให้นำแอป Android ของคุณไปใช้ผ่าน Google Play Store เท่านั้น

ตั้งค่า SDK

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

แก้ไขไฟล์ Manifest ของแอป

เพิ่มข้อมูลต่อไปนี้ลงในไฟล์ Manifest ของแอป

  • บริการที่ขยาย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 เป็นรหัสของออบเจ็กต์แชแนลการแจ้งเตือนดังที่แสดง 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 ที่กําหนดไว้ในไฟล์ Manifest อย่างไรก็ตาม แอปของคุณจะต้องขอสิทธิ์เวอร์ชันรันไทม์ผ่านค่าคงที่ android.permission.POST_NOTIFICATIONS ด้วย แอปของคุณจะไม่ได้รับอนุญาตให้แสดงการแจ้งเตือนจนกว่าผู้ใช้จะให้สิทธิ์นี้

วิธีขอสิทธิ์รันไทม์ใหม่

Kotlin

// 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() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        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)
        }
    }
}

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() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        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 นี้ควรให้ตัวเลือกแก่ผู้ใช้ในการยอมรับหรือปฏิเสธ เช่น ปุ่มตกลงและไม่ขอบคุณ หากผู้ใช้เลือกตกลง ให้ขอสิทธิ์โดยตรง หากผู้ใช้เลือกไม่เป็นไร ให้อนุญาตให้ผู้ใช้ดำเนินการต่อโดยไม่ได้รับการแจ้งเตือน

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

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

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

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

ไม่บังคับ: นำสิทธิ์ POST_NOTIFICATIONS ออก

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

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

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

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

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

โทเค็นการลงทะเบียนอาจเปลี่ยนแปลงในกรณีต่อไปนี้

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

เรียกข้อมูลโทเค็นการลงทะเบียนปัจจุบัน

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

Kotlin

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()
})

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();
        }
    });

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

การทำงานของ onNewToken callback จะเริ่มต้นทุกครั้งที่มีการสร้างโทเค็นใหม่

Kotlin

/**
 * 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)
}

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);
}

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

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

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

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

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

เมื่อสร้างโทเค็นการลงทะเบียน FCM แล้ว ไลบรารีจะอัปโหลดตัวระบุและข้อมูลการกําหนดค่าไปยัง Firebase หากต้องการป้องกันไม่ให้ระบบสร้างโทเค็นโดยอัตโนมัติ ให้ปิดใช้การเก็บรวบรวม Analytics และการสร้าง FCM อัตโนมัติ (คุณต้องปิดใช้ทั้ง 2 อย่าง) โดยเพิ่มค่าข้อมูลเมตาต่อไปนี้ลงใน 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 อีกครั้ง ให้เรียกใช้รันไทม์ ดังนี้

Kotlin

Firebase.messaging.isAutoInitEnabled = true

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

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

setAnalyticsCollectionEnabled(true);

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

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

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

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

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