| Chọn nền tảng: | iOS+ Android Web Flutter Unity C++ |
Hướng dẫn này mô tả cách bắt đầu sử dụng Firebase Cloud Messaging trong ứng dụng khách Android để bạn có thể gửi thông báo một cách đáng tin cậy.
FCM ứng dụng cần có thiết bị chạy Android 6.0 trở lên và đã cài đặt ứng dụng Cửa hàng Google Play hoặc trình mô phỏng chạy Android 6.0 có API Google. Xin lưu ý rằng bạn không chỉ có thể triển khai ứng dụng Android thông qua Cửa hàng Google Play.
Thiết lập SDK
Nếu bạn chưa thực hiện, hãy thêm Firebase vào dự án Android.
Để có trải nghiệm tối ưu với FCM, bạn nên bật Google Analytics trong dự án của mình. Google Analytics là yêu cầu bắt buộc đối với tính năng báo cáo về việc gửi thông báo cho FCM.
Chỉnh sửa tệp kê khai ứng dụng
Thêm nội dung sau vào tệp kê khai của ứng dụng:
- Một dịch vụ mở rộng
FirebaseMessagingService. Bạn cần thực hiện việc này nếu muốn xử lý thông báo ngoài việc nhận thông báo trên các ứng dụng ở chế độ nền. Để nhận thông báo trong các ứng dụng ở nền trước, nhận tải trọng dữ liệu và nhiều nội dung khác, bạn phải mở rộng dịch vụ này. - (Không bắt buộc) Trong thành phần của ứng dụng, các phần tử siêu dữ liệu để đặt biểu tượng và màu thông báo mặc định. Android sử dụng các giá trị này bất cứ khi nào thông báo đến không đặt rõ ràng biểu tượng hoặc màu.
- (Không bắt buộc) Từ Android 8.0 (cấp độ API 26) trở lên,
các kênh thông báo được hỗ trợ và nên dùng. FCM cung cấp một kênh thông báo mặc định
với các chế độ cài đặt cơ bản. Nếu bạn muốn
tạo và sử dụng kênh mặc định của riêng mình,
hãy đặt
default_notification_channel_idthành mã của đối tượng kênh thông báo như minh hoạ; FCM sẽ sử dụng giá trị này bất cứ khi nào thông báo đến không đặt rõ ràng một kênh thông báo. Để tìm hiểu thêm, hãy xem bài viết Quản lý kênh thông báo.
<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" />
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id" />
Yêu cầu quyền gửi thông báo trong thời gian chạy trên Android 13 trở lên
Android 13 ra mắt một quyền khi bắt đầu chạy mới để hiển thị thông báo. Quyền này ảnh hưởng đến tất cả các ứng dụng chạy trên Android 13 trở lên sử dụng FCM thông báo.
Theo mặc định, SDK FCM (phiên bản 23.0.6 trở lên) bao gồm quyền
POST_NOTIFICATIONS
được xác định trong tệp kê khai. Tuy nhiên, ứng dụng của bạn cũng cần yêu cầu phiên bản quyền này trong thời gian chạy bằng cách sử dụng hằng số android.permission.POST_NOTIFICATIONS. Ứng dụng của bạn sẽ không được phép hiển thị thông báo cho đến khi người dùng cấp quyền này.
Cách yêu cầu quyền khi bắt đầu chạy mới:
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); } } }
Thông thường, bạn nên hiển thị giao diện người dùng giải thích cho người dùng về các tính năng sẽ được bật nếu họ cấp quyền cho ứng dụng đăng thông báo. Giao diện người dùng này phải cung cấp cho người dùng các lựa chọn đồng ý hoặc từ chối, chẳng hạn như nút OK và Không, cảm ơn. Nếu người dùng chọn OK, hãy trực tiếp yêu cầu quyền. Nếu người dùng chọn Không, cảm ơn, hãy cho phép người dùng tiếp tục mà không cần thông báo.
Quyền thông báo cho các ứng dụng nhắm đến Android 12L (cấp độ API 32) trở xuống
Android sẽ tự động yêu cầu người dùng cấp quyền vào lần đầu tiên ứng dụng của bạn tạo kênh thông báo, miễn là ứng dụng ở nền trước. Tuy nhiên, có những lưu ý quan trọng về thời điểm tạo kênh và yêu cầu quyền:
- Nếu ứng dụng của bạn tạo kênh thông báo đầu tiên khi đang chạy ở chế độ nền, điều mà SDK FCM thực hiện khi nhận được thông báo FCM, thì Android sẽ không cho phép hiển thị thông báo và sẽ không nhắc người dùng cấp quyền gửi thông báo cho đến lần tiếp theo ứng dụng của bạn được mở. Điều này có nghĩa là mọi thông báo nhận được trước khi ứng dụng của bạn được mở và người dùng chấp nhận quyền sẽ bị mất.
- Bạn nên cập nhật ứng dụng để nhắm đến Android 13 trở lên nhằm tận dụng các API của nền tảng để yêu cầu quyền. Nếu không thể thực hiện việc đó, ứng dụng của bạn nên tạo kênh thông báo trước khi bạn gửi bất kỳ thông báo nào đến ứng dụng để kích hoạt hộp thoại quyền gửi thông báo và đảm bảo không có thông báo nào bị mất. Hãy xem các phương pháp hay nhất về quyền gửi thông báo để biết thêm thông tin.
Không bắt buộc: xoá quyền POST_NOTIFICATIONS
Theo mặc định, SDK FCM bao gồm quyền POST_NOTIFICATIONS.
Nếu ứng dụng của bạn không sử dụng thông báo (thông qua FCM
thông báo, thông qua một SDK khác hoặc do ứng dụng của bạn đăng trực tiếp) và bạn
không muốn ứng dụng của mình bao gồm quyền này, thì bạn có thể xoá quyền đó bằng cách sử dụng dấu hiệu
của trình hợp nhất tệp kê khai
remove. Xin lưu ý rằng việc xoá quyền này sẽ ngăn hiển thị
tất cả thông báo, không chỉ FCM thông báo. Thêm nội dung sau vào tệp kê khai của ứng dụng:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" tools:node="remove"/>
Truy cập vào Mã cài đặt Firebase
Khi khởi động ứng dụng lần đầu, SDK FCM sẽ đăng ký thực thể ứng dụng với
FCM và trả về giá trị nhận dạng cho thực thể ứng dụng. Nếu muốn nhắm đến các thực thể ứng dụng riêng lẻ, bạn cần truy cập vào giá trị nhận dạng này bằng cách
mở rộng
FirebaseMessagingService và ghi đè
onRegistered().
Theo phương pháp hay nhất, hãy truy xuất giá trị nhận dạng được cập nhật mới nhất vì giá trị nhận dạng có thể xoay vòng sau lần khởi động đầu tiên.
Bật tính năng đăng ký thông qua Mã cài đặt Firebase
Để bật tính năng đăng ký thực thể ứng dụng với FCM bằng Mã cài đặt Firebase (FID), hãy thêm cờ siêu dữ liệu sau vào tệpAndroidManifest.xml của bạn:
<meta-data android:name="firebase_messaging_installation_id_enabled" android:value="true" />
Triển khai lệnh gọi lại onRegistered()
Các thực thể ứng dụng được nhắm đến bằng Mã cài đặt Firebase (FID) sau khi đăng ký
với FCM. Để truy xuất FID khi đăng ký, hãy triển khai lệnh gọi lại
onRegistered().
Sau khi đăng ký một thực thể ứng dụng, SDK FCM
sẽ tự động theo dõi các thay đổi về FID và gọi lệnh gọi lại khi phát hiện thấy thay đổi.
Khi bật tính năng tự động khởi chạy, SDK FCM sẽ tự động đồng bộ hoá với phần phụ trợ FCM để duy trì trạng thái đăng ký mới nhất và gọi lệnh gọi lại để đảm bảo máy chủ ứng dụng của bạn có giá trị nhận dạng hiện tại. Để tránh mất FID hoặc
FID lỗi thời, bạn nên gửi FID đến máy chủ ứng dụng của mình bất cứ khi nào lệnh gọi lại này kích hoạt.
Kotlin
/** * There are three scenarios when `onRegistered` is called: * 1) Every time a manual `register()` call finishes successfully * 2) Whenever the FID is changed and the app is re-registered with FCM via the new FID. * 3) Automatically on app startup or routine sync when auto-initialization is enabled. * Under #2, there are three scenarios when the existing FID is changed: * A) App is restored to a new device * B) User uninstalls/reinstalls the app * C) User clears app data */ override fun onRegistered(installationId: String) { Log.d(TAG, "Registered installation ID: $installationId") // Send the Firebase Installation ID to your app server. sendRegistrationToServer(installationId) }
Java
/** * There are three scenarios when `onRegistered` is called: * 1) Every time a manual `register()` call finishes successfully * 2) Whenever the FID is changed and the app is re-registered with FCM via the new FID * 3) Automatically on app startup or routine sync when auto-initialization is enabled. * Under #2, there are three scenarios when the existing FID is changed: * A) App is restored to a new device * B) User uninstalls/reinstalls the app * C) User clears app data */ @Override public void onRegistered(@NonNull String installationId) { Log.d(TAG, "Registered installation ID: " + installationId); // Send the Firebase Installation ID to your app server. sendRegistrationToServer(installationId); }
Đăng ký theo cách thủ công khi tắt tính năng tự động khởi chạy
Nếu bạn phải tắt tính năng tự động khởi chạy, thì FCM SDK sẽ không tự động đồng bộ hoá hoặc kích hoạt lệnh gọi lại
khi khởi động.onRegistered() Bạn nên bật lại tính năng tự động khởi chạy sau khi
cấp quyền thông báo. Để tìm hiểu thêm, hãy xem
bài viết Bật lại tính năng tự động khởi chạy.
Nếu phải tắt tính năng tự động khởi chạy, hãy gọi
FirebaseMessaging.getInstance().register() khi khởi động ứng dụng để kích hoạt
quá trình đăng ký và gửi FID thông qua
onRegistered() lệnh gọi lại. Bạn có thể
thực thi lệnh gọi này trong
onCreate() phương thức của Activity chính.
Kotlin
// Trigger manual registration if auto-initialization is turned off. // Consider calling this every time the app starts to guarantee sync status. FirebaseMessaging.getInstance().register() .addOnCompleteListener(this) { task -> if (!task.isSuccessful()) { // Registration failed. Consider retrying the registration with exponential backoff. Log.w(TAG, "Failed to register with Firebase Cloud Messaging", task.exception) } // Success! The Firebase Installation ID can be used to target messages to this app // instance and will be delivered asynchronously to your `onRegistered()` callback. }
Java
// Trigger manual registration if auto-initialization is turned off. // Consider calling this every time the app starts to guarantee sync status. FirebaseMessaging.getInstance().register() .addOnCompleteListener(task -> { if (!task.isSuccessful()) { // Registration failed. Consider retrying the registration with exponential backoff. Log.w(TAG, "Failed to register with Firebase Cloud Messaging", task.exception) } // Success! The Firebase Installation ID can be used to target messages to this app // instance and will be delivered asynchronously to your `onRegistered()` callback. });
Truy cập vào mã thông báo đăng ký FCM (không dùng nữa)
Khi khởi động ứng dụng lần đầu, SDK FCM sẽ tạo mã thông báo đăng ký
cho thực thể ứng dụng khách. Nếu muốn nhắm đến các thực thể ứng dụng riêng lẻ hoặc
tạo nhóm thiết bị, bạn cần truy cập vào mã thông báo này bằng cách mở rộng
FirebaseMessagingService và ghi đè onNewToken. Vì mã thông báo có thể xoay vòng sau lần khởi động đầu tiên, nên bạn nên truy xuất mã thông báo đăng ký được cập nhật mới nhất.
Mã thông báo đăng ký có thể thay đổi khi:
- Ứng dụng được khôi phục trên một thiết bị mới
- Người dùng gỡ cài đặt/cài đặt lại ứng dụng
- Người dùng xoá dữ liệu ứng dụng.
Truy xuất mã thông báo đăng ký hiện tại
Khi cần truy xuất mã thông báo hiện tại, hãy gọi
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(); } });
Theo dõi quá trình tạo mã thông báo
Lệnh gọi lại onNewToken sẽ kích hoạt bất cứ khi nào một mã thông báo mới được tạo.
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); }
Sau khi nhận được mã thông báo, bạn có thể gửi mã thông báo đó đến máy chủ ứng dụng và lưu trữ bằng phương thức bạn muốn.
Kiểm tra Dịch vụ Google Play
Các ứng dụng dựa vào SDK Dịch vụ Play phải luôn kiểm tra thiết bị để tìm tệp APK Dịch vụ Google Play tương thích trước khi truy cập vào các tính năng của Dịch vụ Google Play. Để tìm hiểu thêm, hãy xem bài viết thiết lập Dịch vụ Google Play. Bạn nên thực hiện việc này ở hai nơi: trong phương thức onCreate() của hoạt động chính và trong phương thức onResume() của hoạt động đó. Quá trình kiểm tra trong onCreate() đảm bảo rằng ứng dụng không thể sử dụng nếu không kiểm tra thành công. Quá trình kiểm tra trong onResume() đảm bảo rằng nếu người dùng quay lại ứng dụng đang chạy bằng một số cách khác, chẳng hạn như thông qua nút quay lại, thì quá trình kiểm tra vẫn được thực hiện.
Nếu thiết bị không có phiên bản Dịch vụ Google Play tương thích, thì ứng dụng của bạn có thể gọi
GoogleApiAvailability.makeGooglePlayServicesAvailable()
để cho phép người dùng tải Dịch vụ Google Play xuống từ Cửa hàng Play.
Ngăn tự động khởi chạy
Khi tạo một FCM đăng ký, thư viện sẽ tải
giá trị nhận dạng và dữ liệu cấu hình lên Firebase. Nếu bạn muốn ngăn quá trình tự động đăng ký, hãy tắt tính năng thu thập Analytics và tự động khởi chạy FCM (bạn phải tắt cả hai) bằng cách thêm các giá trị siêu dữ liệu này vào 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" />
Bật lại tính năng tự động khởi chạy
Để bật lại tính năng tự động khởi chạy FCM, hãy thực hiện lệnh gọi trong thời gian chạy:
Kotlin
Firebase.messaging.isAutoInitEnabled = true
Java
FirebaseMessaging.getInstance().setAutoInitEnabled(true);
Để bật lại tính năng thu thập Analytics, hãy gọi phương thức
setAnalyticsCollectionEnabled()
của lớp FirebaseAnalytics. Ví dụ:
setAnalyticsCollectionEnabled(true);
Các giá trị này sẽ tồn tại trong các lần khởi động lại ứng dụng sau khi được đặt.
Gửi thông báo
Để đảm bảo rằng ứng dụng khách Android của bạn được thiết lập đúng cách, bạn có thể gửi thông báo thử nghiệm bằng cách làm theo hướng dẫn sau:
Cài đặt và chạy ứng dụng trên thiết bị mục tiêu.
Đảm bảo ứng dụng ở chế độ nền trên thiết bị.
Trong bảng điều khiển Firebase, hãy chuyển đến DevOps và mức độ gắn bó > Nhắn tin
Tạo một chiến dịch.
Nếu đây là thông báo đầu tiên của bạn:
Chọn Tạo chiến dịch đầu tiên.
Chọn Thông báo Firebase rồi chọn Tạo.
Nếu bạn đã tạo chiến dịch trước đó:
Trên thẻ Chiến dịch, hãy chọn Chiến dịch mới.
Nhấp vào Thông báo.
Nhập nội dung thông báo. Tất cả các trường khác đều không bắt buộc.
Chọn Gửi thông báo thử nghiệm trong ngăn bên phải.
Trong trường có nhãn Thêm mã thông báo đăng ký FCM, hãy nhập mã thông báo đăng ký mà bạn đã nhận được trong một phần trước của hướng dẫn này.
Chọn Kiểm thử.
Thiết bị khách mục tiêu (có ứng dụng ở chế độ nền) sẽ nhận được thông báo.
Để xem thông tin chi tiết về việc gửi thông báo đến ứng dụng của bạn, hãy chuyển đến trang tổng quan DevOps và mức độ gắn bó > Nhắn tin > Báo cáo trong bảng điều khiển Firebase. Trang tổng quan này ghi lại số lượng thông báo đã gửi và mở trên thiết bị Apple và Android, cùng với dữ liệu về "số lượt hiển thị" (thông báo mà người dùng nhìn thấy) cho các ứng dụng Android.
Các bước tiếp theo
Sau khi bạn hoàn tất các bước thiết lập, sau đây là một vài lựa chọn để tiếp tục sử dụng FCM cho Android: