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

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

ตั้งค่า SDK

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

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

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

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

โดยค่าเริ่มต้น 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();
        }
    });

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

Callback ของ 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

แอปที่ใช้ SDK บริการ Google Play ควรตรวจสอบอุปกรณ์สำหรับ APK ของบริการ Google Play ที่ใช้งานร่วมกันได้ก่อน การเข้าถึงฟีเจอร์ของบริการ Google Play ขอแนะนำให้ดำเนินการใน สองที่: ในเมธอด 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