ตั้งค่าแอปไคลเอ็นต์ 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+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() {
    // 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+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()
})

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 จะทํางานทุกครั้งที่มีการสร้างโทเค็นใหม่

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

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+KTX

Firebase.messaging.isAutoInitEnabled = true

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

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

setAnalyticsCollectionEnabled(true);

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

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

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

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

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