ไคลเอนต์ 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>
<!-- 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" />
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