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

ดู การอนุญาตรันไทม์การแจ้งเตือน เพื่อดูแนวทางปฏิบัติที่ดีที่สุดเพิ่มเติมว่าเมื่อใดที่แอปของคุณควรขอสิทธิ์ 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() :

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 ขอแนะนำให้ทำเช่นนี้ในสองที่: ในเมธอด 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 อีกครั้ง ให้ทำการเรียกรันไทม์:

Kotlin+KTX

Firebase.messaging.isAutoInitEnabled = true

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

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

setAnalyticsCollectionEnabled(true);

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

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

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

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

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