获取我们在 Firebase 峰会上发布的所有信息,了解 Firebase 可如何帮助您加快应用开发速度并满怀信心地运行应用。了解详情

Thiết lập ứng dụng khách Nhắn tin qua đám mây của Firebase trên Android

Ứng dụng khách FCM yêu cầu thiết bị chạy Android 4.4 trở lên cũng đã cài đặt ứng dụng Cửa hàng Google Play hoặc trình mô phỏng chạy Android 4.4 với API Google. Lưu ý rằng bạn không bị giới hạn trong việc triển khai các ứng dụng Android của mình thông qua Cửa hàng Google Play.

Thiết lập SDK

Phần này bao gồm các nhiệm vụ bạn có thể đã hoàn thành nếu bạn đã bật các tính năng Firebase khác cho ứng dụng của mình. Nếu bạn chưa có, hãy thêm Firebase vào dự án Android của bạn

Chỉnh sửa tệp kê khai ứng dụng của bạn

Thêm phần sau vào tệp kê khai ứng dụng của bạn:

  • Một dịch vụ mở rộng FirebaseMessagingService . Điều này là bắt buộc nếu bạn muốn thực hiện bất kỳ xử lý tin nhắn nà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, gửi tin nhắn ngược dòng, v.v., bạn phải mở rộng dịch vụ này.
  • <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
  • (Tùy chọn) Trong thành phần ứ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 tin nhắn đến không đặt biểu tượng hoặc màu sắc một cách rõ ràng.
  • <!-- 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" />
  • (Tùy chọn) Từ Android 8.0 (API cấp 26) trở lên, các kênh thông báo được hỗ trợ và khuyến nghị. FCM cung cấp một kênh thông báo mặc định với các 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_id thành ID của đối tượng kênh thông báo của bạn như được minh họa; FCM sẽ sử dụng giá trị này bất cứ khi nào các tin nhắn đến không đặt kênh thông báo một cách rõ ràng. Để tìm hiểu thêm, hãy xem Quản lý kênh thông báo .
  • <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 thông báo thời gian chạy trên Android 13+

Android 13 giới thiệu quyền thời gian chạy mới để hiển thị thông báo. Điều 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 thông báo FCM.

Theo mặc định, FCM SDK (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 sẽ cần yêu cầu phiên bản thời gian chạy của quyền này thông qua 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.

Để yêu cầu quyền thời gian chạy mới:

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

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

Nói chung, bạn nên hiển thị giao diện người dùng giải thích cho người dùng 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 sẽ cung cấp các tùy chọn người dùng đồng ý hoặc từ chối, chẳng hạn như nút Đồng ý 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ó thông báo.

Xem Quyền thời gian chạy thông báo để biết thêm các phương pháp hay nhất về thời điểm ứng dụng của bạn nên yêu cầu quyền POST_NOTIFICATIONS từ người dùng.

Quyền thông báo cho các ứng dụng nhắm mục tiêu Android 12L (API cấp 32) trở xuống

Android 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 gian tạo kênh và yêu cầu cấp quyền:

  • Nếu ứng dụng của bạn tạo kênh thông báo đầu tiên khi ứng dụng đang chạy trong 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 về quyền thông báo cho đến lần tiếp theo thời gian ứ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 .
  • Chúng tôi thực sự khuyên bạn nên cập nhật ứng dụng của mình để nhắm mục tiêu Android 13+ 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ể, ứng dụng của bạn nên tạo các 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 thông báo và đảm bảo không có thông báo nào bị mất. Xem các phương pháp hay nhất về quyền thông báo để biết thêm thông tin.

Tùy chọn: xóa quyền POST_NOTIFICATIONS

Theo mặc định, FCM SDK bao gồm quyền POST_NOTIFICATIONS . Nếu ứng dụng của bạn không sử dụng tin nhắn thông báo (cho dù thông qua thông báo FCM, thông qua 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, bạn có thể xóa nó bằng cách sử dụng điểm đánh dấu remove của sáp nhập tệp kê khai . Hãy nhớ rằng việc xóa quyền này sẽ ngăn không cho hiển thị tất cả các thông báo, không chỉ thông báo FCM. Thêm phần sau vào tệp kê khai của ứng dụng của bạn:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" tools:node="remove"/>

Truy cập mã thông báo đăng ký thiết bị

Khi khởi động lần đầu ứng dụng của bạn, FCM SDK tạo mã thông báo đăng ký cho phiên bản ứng dụng khách. Nếu bạn muốn nhắm mục tiêu các thiết bị đơn lẻ hoặc tạo nhóm thiết bị, bạn sẽ cần truy cập mã thông báo này bằng cách mở rộng FirebaseMessagingService và ghi đè onNewToken .

Phần này mô tả cách truy xuất mã thông báo và cách theo dõi các thay đổi đối với mã thông báo. Vì mã thông báo có thể được xoay sau khi khởi động ban đầu, bạn thực sự 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 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 xóa dữ liệu ứng dụng.

Lấy mã thông báo đăng ký hiện tại

Khi bạn cần truy xuất mã thông báo hiện tại, hãy gọi FirebaseMessaging.getInstance().getToken() :

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

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

Giám sát việc tạo mã thông báo

Lệnh gọi lại onNewToken kích hoạt bất cứ khi nào mã thông báo mới được tạo.

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

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

Sau khi nhận được mã thông báo, bạn có thể gửi mã đến máy chủ ứng dụng của mình và lưu trữ bằng phương pháp ưa thích của bạn.

Kiểm tra các dịch vụ của Google Play

Các ứng dụng dựa trên SDK dịch vụ Play phải luôn kiểm tra thiết bị để tìm APK dịch vụ Google Play tương thích trước khi truy cập các tính năng dịch vụ của 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 nó. Kiểm tra onCreate() đảm bảo rằng ứng dụng không thể được sử dụng nếu không kiểm tra thành công. Việc kiểm tra onResume() đảm bảo rằng nếu người dùng quay lại ứng dụng đang chạy thông qua một số phương tiện khác, chẳng hạn như thông qua nút quay lại, thì việc kiểm tra vẫn được thực hiện.

Nếu thiết bị không có phiên bản tương thích của các dịch vụ Google Play, ứng dụng của bạn có thể gọi GoogleApiAvailability.makeGooglePlayServicesAvailable() để cho phép người dùng tải xuống các dịch vụ của Google Play từ Cửa hàng Play.

Ngăn tự động khởi chạy

Khi mã thông báo đăng ký FCM được tạo, thư viện sẽ tải dữ liệu nhận dạng và cấu hình lên Firebase. Nếu bạn muốn ngăn tự động tạo mã thông báo, hãy tắt 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 của bạn:

<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 động FCM, hãy thực hiện cuộc gọi thời gian chạy:

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

Kotlin+KTX

Firebase.messaging.isAutoInitEnabled = true

Để bật lại bộ sưu tậ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 vẫn tồn tại qua các lần khởi động lại ứng dụng sau khi được đặt.

Bước tiếp theo

Sau khi ứng dụng khách được thiết lập, bạn đã sẵn sàng để bắt đầu gửi tin nhắn xuôi dòng bằng trình tổng hợp Thông báo . Chức năng này được thể hiện trong mẫu khởi động nhanh mà bạn có thể tải xuống, chạy và xem lại.

Để thêm hành vi khác, nâng cao hơn vào ứng dụng của mình, bạn có thể khai báo một bộ lọc ý định và triển khai một hoạt động để phản hồi các tin nhắn đến. Để biết chi tiết, hãy xem hướng dẫn gửi tin nhắn từ máy chủ ứng dụng:

Hãy nhớ rằng, để tận dụng các tính năng này, bạn sẽ cần triển khai máy chủ và các procotols máy chủ (HTTP hoặc XMPP) hoặc triển khai SDK quản trị.