Bắt đầu sử dụng Giải pháp gửi thông báo qua đám mây của Firebase trong các ứng dụng C++

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 các ứng dụng máy khách C++ để bạn có thể gửi thông báo một cách đáng tin cậy.

Để viết ứng dụng khách Firebase Cloud Messaging nhiều nền tảng bằng C++, hãy sử dụng API Firebase Cloud Messaging. SDK C++ hoạt động cho cả nền tảng Android và Apple, với một số chế độ thiết lập bổ sung cần thiết cho mỗi nền tảng. Để tìm hiểu thêm về cách C++ SDK cho iOS và Android hoạt động với FCM, hãy xem phần Tìm hiểu về Firebase cho C++.

Thiết lập Firebase và FCM SDK

Android

  1. Nếu bạn chưa thực hiện, hãy thêm Firebase vào dự án C++.

    • Trong hướng dẫn thiết lập được liên kết, hãy xem các yêu cầu về thiết bị và ứng dụng để sử dụng SDK Firebase C++, bao gồm cả đề xuất sử dụng CMake để tạo ứng dụng.

    • Trong tệp build.gradle cấp dự án, hãy nhớ thêm kho lưu trữ Maven của Google vào cả hai mục buildscript và allprojects.

  2. Tạo đối tượng Ứng dụng Firebase, truyền vào môi trường JNI và Hoạt động:

    app = ::firebase::App::Create(::firebase::AppOptions(), jni_env, activity);

  3. Xác định một lớp triển khai giao diện firebase::messaging::Listener.

  4. Khởi chạy FCM, truyền vào Ứng dụng và Trình nghe đã tạo:

    ::firebase::messaging::Initialize(app, listener);

  5. Các ứng dụng dựa vào SDK Dịch vụ Google Play phải kiểm tra thiết bị để tìm APK Dịch vụ Google Play tương thích trước khi truy cập vào các tính năng. Để tìm hiểu thêm, hãy tham khảo bài viết Kiểm tra APK Dịch vụ Google Play.

iOS+

  1. Nếu bạn chưa thực hiện, hãy thêm Firebase vào dự án C++. Sau đó, để thiết lập dự án cho FCM:
    1. Trong Podfile của dự án, hãy thêm phần phụ thuộc FCM:
      pod 'FirebaseMessaging'
    2. Kéo các khung firebase.framework và firebase_messaging.framework vào dự án Xcode của bạn từ Firebase C++ SDK.
  2. Tải khoá xác thực APN lên Firebase. Nếu bạn chưa có khoá xác thực APNs, hãy nhớ tạo một khoá trong Trung tâm thành viên của nhà phát triển Apple.

    1. Trong bảng điều khiển Firebase, hãy chuyển đến phần Cài đặt > Chung. Sau đó, hãy nhấp vào thẻ Cloud Messaging (Gửi thông báo qua đám mây).
    2. Trong phần Khoá xác thực APNs trong mục Cấu hình ứng dụng iOS, hãy nhấp vào Tải lên để tải khoá xác thực phát triển, khoá xác thực sản xuất hoặc cả hai. Bạn phải cung cấp ít nhất một biểu trưng.
    3. Duyệt đến vị trí bạn đã lưu khoá, chọn khoá đó rồi nhấp vào Mở. Thêm mã khoá cho khoá (có trong Trung tâm thành viên của Apple Developer) rồi nhấp vào Tải lên.
  3. Định cấu hình dự án Xcode để bật Thông báo đẩy:

    1. Chọn dự án trong Navigator area (Khu vực điều hướng).
    2. Chọn mục tiêu dự án trong Editor area (Khu vực trình chỉnh sửa).
    3. Chọn thẻ Chung trong vùng Trình chỉnh sửa.

      1. Di chuyển đến Linked Frameworks and Libraries (Thư viện và khung được liên kết), sau đó nhấp vào nút + để thêm khung.
      2. Trong cửa sổ xuất hiện, hãy di chuyển đến UserNotifications.framework, nhấp vào mục này rồi nhấp vào Add (Thêm).

        Khung này chỉ xuất hiện trong Xcode phiên bản 8 trở lên và là yêu cầu bắt buộc đối với thư viện này.

    4. Chọn thẻ Capabilities (Khả năng) trong Editor area (Khu vực trình chỉnh sửa).

      1. Chuyển Thông báo đẩy sang trạng thái Bật.
      2. Di chuyển đến Chế độ nền, sau đó chuyển sang Bật.
      3. Chọn Thông báo từ xa trong phần Chế độ nền.
  4. Tạo đối tượng Ứng dụng Firebase:

    app = ::firebase::App::Create(::firebase::AppOptions());

  5. Xác định một lớp triển khai giao diện firebase::messaging::Listener.

  6. Khởi động Giải pháp gửi thông báo qua đám mây của Firebase, truyền vào Ứng dụng và Trình nghe đã tạo:

    ::firebase::messaging::Initialize(app, listener);

Truy cập vào Mã cài đặt Firebase

Bật tính năng đăng ký bằng Mã cài đặt Firebase

Để cho phép đăng ký phiên bản ứng dụng của bạn bằng FCM thông qua Mã nhận dạng lượt cài đặt Firebase (FID), trước tiên, bạn phải bật FID trong cấu hình của ứng dụng cho cả nền tảng Android và Apple:

Android

Thêm phần tử <meta-data> sau vào bên trong phần tử <application> của AndroidManifest.xml:

<meta-data android:name="firebase_messaging_installation_id_enabled"
           android:value="true" />

Swift

Thêm khoá FirebaseMessagingInstallationIdEnabled vào Info.plist rồi đặt khoá đó thành YES:

FirebaseMessagingInstallationIdEnabled = YES

Triển khai trình nghe onRegistrationReceived

Khi khởi chạy thư viện Firebase Cloud Messaging, thư viện này sẽ đăng ký phiên bản ứng dụng khách để nhận thông báo bằng cách sử dụng Mã nhận dạng lượt cài đặt Firebase (FID). Ứng dụng sẽ nhận được FID bằng lệnh gọi lại OnRegistrationReceived. Lệnh gọi lại này phải được xác định trong quá trình triển khai firebase::messaging::Listener:

class MyListener : public firebase::messaging::Listener {
 public:
  void OnRegistrationReceived(const char* installation_id) override {
    LogMessage("Received Firebase Installation ID: %s", installation_id);
    // TODO: Send the Firebase Installation ID (FID) to your app server to
    // target this device for messages.
  }
};

Nếu bạn muốn nhắm đến một phiên bản ứng dụng cụ thể, hãy gửi FID đến máy chủ ứng dụng và lưu trữ FID đó bằng phương thức bạn muốn.

Đăng ký theo cách thủ công khi tính năng khởi chạy tự động bị tắt

Bạn cũng có thể kích hoạt quá trình đăng ký theo cách thủ công bằng FCM trong thời gian chạy bằng cách sử dụng Register():

// Manually register with FCM
firebase::Future<void> register_future = firebase::messaging::Register();
register_future.OnCompletion([](const firebase::Future<void>& future) {
  if (future.status() == firebase::kFutureStatusComplete &&
      future.error() == 0) {
    // Note: The registered Firebase Installation ID is delivered to the
    // OnRegistrationReceived callback.
    LogMessage("Registered with FCM");
  }
});

Truy cập vào mã thông báo đăng ký FCM (không dùng nữa)

Khi khởi chạy thư viện Firebase Cloud Messaging, mã thông báo đăng ký sẽ được yêu cầu cho phiên bản ứng dụng khách. Ứng dụng sẽ nhận được mã thông báo bằng lệnh gọi lại OnTokenReceived. Lệnh này phải được xác định trong lớp triển khai firebase::messaging::Listener.

Nếu muốn nhắm đến một phiên bản ứng dụng cụ thể, bạn cần có quyền truy cập vào mã thông báo này.

Lưu ý về việc gửi tin nhắn trên Android

Khi ứng dụng hoàn toàn không chạy và người dùng nhấn vào thông báo, theo mặc định, thông báo sẽ không được định tuyến thông qua lệnh gọi lại tích hợp sẵn của FCM. Trong trường hợp này, tải trọng thông báo được nhận thông qua một Intent dùng để khởi động ứng dụng. Để FCM chuyển tiếp các tin nhắn đến này đến lệnh gọi lại thư viện C++, bạn cần ghi đè phương thức onNewIntent trong Hoạt động và truyền Intent đến MessageForwardingService.

import com.google.firebase.messaging.MessageForwardingService;

class MyActivity extends Activity {
  private static final String TAG = "MyActvity";

  @Override
  protected void onNewIntent(Intent intent) {
    Log.d(TAG, "A message was sent to this app while it was in the background.");
    Intent message = new Intent(this, MessageForwardingService.class);
    message.setAction(MessageForwardingService.ACTION_REMOTE_INTENT);
    message.putExtras(intent);
    message.setData(intent.getData());
    // For older versions of Firebase C++ SDK (< 7.1.0), use `startService`.
    // startService(message);
    MessageForwardingService.enqueueWork(this, message);
  }
}

Tin nhắn nhận được khi ứng dụng ở chế độ nền sẽ có nội dung của trường thông báo được dùng để điền thông báo trên khay hệ thống, nhưng nội dung thông báo đó sẽ không được truyền đến FCM. Tức là Message::notification sẽ có giá trị rỗng.

Tóm lại:

Trạng thái ứng dụng Thông báo Dữ liệu Cả hai
Nền trước OnMessageReceived OnMessageReceived OnMessageReceived
Thông tin khái quát Khay hệ thống OnMessageReceived Thông báo: khay hệ thống
Dữ liệu: trong phần bổ sung của ý định.

Xử lý thông báo tuỳ chỉnh trên Android

Theo mặc định, thông báo gửi đến ứng dụng sẽ được chuyển đến ::firebase::messaging::Listener::OnMessageReceived, nhưng trong một số trường hợp, bạn có thể muốn ghi đè hành vi mặc định. Để làm việc này trên Android, bạn cần viết các lớp tuỳ chỉnh mở rộng com.google.firebase.messaging.cpp.ListenerService cũng như cập nhật AndroidManifest.xml của dự án.

Ghi đè phương thức ListenerService

ListenerService là lớp Java chặn các tin nhắn đến được gửi đến ứng dụng và định tuyến các tin nhắn đó đến thư viện C++. Khi ứng dụng ở nền trước (hoặc khi ứng dụng ở nền sau và nhận được tải trọng chỉ có dữ liệu), các thông báo sẽ truyền qua một trong các lệnh gọi lại được cung cấp trên lớp này. Để thêm hành vi tuỳ chỉnh vào quá trình xử lý thông báo, bạn cần mở rộng ListenerService mặc định của FCM:

import com.google.firebase.messaging.cpp.ListenerService;

class MyListenerService extends ListenerService {

Bằng cách ghi đè phương thức ListenerService.onMessageReceived, bạn có thể thực hiện các hành động dựa trên đối tượng RemoteMessage nhận được và lấy dữ liệu thông báo:

@Override
public void onMessageReceived(RemoteMessage message) {
  Log.d(TAG, "A message has been received.");
  // Do additional logic...
  super.onMessageReceived(message);
}

ListenerService cũng có một số phương thức khác ít được sử dụng hơn. Bạn cũng có thể ghi đè các phương thức này. Để biết thêm thông tin, hãy xem tài liệu tham khảo về FirebaseMessagingService.

@Override
public void onDeletedMessages() {
  Log.d(TAG, "Messages have been deleted on the server.");
  // Do additional logic...
  super.onDeletedMessages();
}

@Override
public void onMessageSent(String messageId) {
  Log.d(TAG, "An outgoing message has been sent.");
  // Do additional logic...
  super.onMessageSent(messageId);
}

@Override
public void onSendError(String messageId, Exception exception) {
  Log.d(TAG, "An outgoing message encountered an error.");
  // Do additional logic...
  super.onSendError(messageId, exception);
}

Cập nhật AndroidManifest.xml

Sau khi bạn viết các lớp tuỳ chỉnh, bạn phải thêm các lớp đó vào AndroidManifest.xml để có hiệu lực. Hãy đảm bảo tệp kê khai có chứa các công cụ sáp nhập bằng cách khai báo thuộc tính thích hợp bên trong thẻ <manifest>, như sau:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.firebase.messaging.cpp.samples"
    xmlns:tools="http://schemas.android.com/tools">

Trong tệp lưu trữ firebase_messaging_cpp.aar, có một tệp AndroidManifest.xml khai báo ListenerService mặc định của FCM. Tệp kê khai này thường được hợp nhất với tệp kê khai dành riêng cho dự án, đây là cách ListenerService có thể chạy. ListenerService này cần được thay thế bằng dịch vụ trình nghe tuỳ chỉnh. Bạn có thể thực hiện việc này bằng cách xoá ListenerService mặc định và thêm Dịch vụ tuỳ chỉnh. Bạn có thể thực hiện việc này bằng các dòng sau trong tệp AndroidManifest.xml của dự án:

<service android:name="com.google.firebase.messaging.cpp.ListenerService"
         tools:node="remove" />
<service android:name="com.google.firebase.messaging.cpp.samples.MyListenerService"
         android:exported="false">
  <intent-filter>
    <action android:name="com.google.firebase.MESSAGING_EVENT"/>
  </intent-filter>
</service>

Các phiên bản mới của SDK C++ của Firebase (từ 7.1.0 trở đi) sử dụng JobIntentService, yêu cầu sửa đổi thêm trong tệp AndroidManifest.xml.

<service android:name="com.google.firebase.messaging.MessageForwardingService"
     android:permission="android.permission.BIND_JOB_SERVICE"
     android:exported="false" >
</service>

Ngăn quá trình khởi chạy tự động

FCM tạo mã thông báo đăng ký để nhắm mục tiêu thực thể ứng dụng. Khi một mã thông báo được tạo, thư viện sẽ tải dữ liệu về cấu hình và giá trị nhận dạng lên Firebase. Nếu muốn nhận được sự chọn tham gia rõ ràng trước khi sử dụng mã thông báo, bạn có thể ngăn việc tạo mã thông báo tại thời điểm định cấu hình bằng cách tắt FCM (và Analytics trên Android). Để làm việc này, hãy thêm một giá trị siêu dữ liệu vào Info.plist (không phải GoogleService-Info.plist) trên các nền tảng của Apple hoặc AndroidManifest.xml trên Android:

Android

<?xml version="1.0" encoding="utf-8"?>
<application>
  <meta-data android:name="firebase_messaging_auto_init_enabled"
             android:value="false" />
  <meta-data android:name="firebase_analytics_collection_enabled"
             android:value="false" />
</application>

Swift

FirebaseMessagingAutoInitEnabled = NO

Để bật lại FCM, bạn có thể thực hiện lệnh gọi thời gian chạy:

::firebase::messaging::SetRegistrationOnInitEnabled(true);

Giá trị này sẽ được giữ lại sau khi ứng dụng khởi động lại.

FCM cho phép gửi các thông báo có chứa một đường liên kết sâu vào ứng dụng của bạn. Để nhận các thông báo có chứa một đường liên kết sâu, bạn phải thêm một bộ lọc ý định mới vào hoạt động xử lý các đường liên kết sâu cho ứng dụng của mình. Bộ lọc ý định này sẽ nắm bắt các đường liên kết sâu của miền. Nếu thông báo của bạn không chứa đường liên kết sâu, thì bạn không cần thực hiện cấu hình này. Trong AndroidManifest.xml:

<intent-filter>
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <data android:host="CHANGE_THIS_DOMAIN.example.com" android:scheme="http"/>
  <data android:host="CHANGE_THIS_DOMAIN.example.com" android:scheme="https"/>
</intent-filter>

Bạn cũng có thể chỉ định ký tự đại diện để giúp bộ lọc ý định linh hoạt hơn. Ví dụ:

<intent-filter>
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <data android:host="*.example.com" android:scheme="http"/>
  <data android:host="*.example.com" android:scheme="https"/>
</intent-filter>

Khi người dùng nhấn vào một thông báo có chứa đường liên kết đến lược đồ và máy chủ lưu trữ mà bạn chỉ định, ứng dụng của bạn sẽ bắt đầu hoạt động bằng bộ lọc ý định này để xử lý đường liên kết.

Các bước tiếp theo

Sau khi hoàn tất các bước thiết lập, bạn có thể chọn một trong số các cách sau để tiếp tục sử dụng FCM cho C++: