Thiết lập ứng dụng nhắn tin qua đám mây của Firebase bằng C++

Để viết ứng dụng Gửi thông báo qua đám mây của Firebase đa nền tảng bằng C++, hãy sử dụng API Gửi thông báo qua đám mây của Firebase. SDK C++ hoạt động cho cả nền tảng Android và Apple, với một số bước thiết lập bổ sung cần thiết cho mỗi nền tảng.

Thiết lập Firebase và SDK FCM

Android

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

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

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

  2. Tạo một đố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 sẽ triển khai giao diện firebase::messaging::Listener.

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

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

  5. Ứ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 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 của các Dịch vụ Google Play.

iOS trở lên

  1. Bạn cần có chứng chỉ APN hợp lệ. Nếu bạn chưa có tài khoản, hãy nhớ tạo một tài khoản trong Trung tâm thành viên dành cho nhà phát triển của Apple.
  2. Nếu bạn chưa thực hiện, hãy thêm Firebase vào dự án C++ của bạn. 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.frameworkfirebase_messaging.framework vào dự án Xcode của bạn từ SDK C++ của Firebase.
  3. Định cấu hình dự án Xcode của bạn để bật Thông báo đẩy:

    1. Chọn dự án trong Navigator4 (Khu vực điều hướng).
    2. Chọn mục tiêu dự án trong Khu vực chỉnh sửa.
    3. Chọn thẻ General (Chung) trong phần Editor khu vực.

      1. Di chuyển xuống Linked Frameworks and Libraries (Khung và thư viện được liên kết), sau đó nhấp vào nút + để thêm các khung.
      2. Trong cửa sổ xuất hiện, hãy di chuyển đến phần UserNotifications.framework, nhấp vào mục đó 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à cần có trong thư viện này.

    4. Chọn thẻ Capability (Chức năng) trong vùng chỉnh sửa.

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

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

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

  6. Khởi chạy 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 được tạo:

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

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

Khi khởi động thư viện Giải pháp gửi thông báo qua đám mây của Firebase, hệ thống sẽ yêu cầu một mã thông báo đăng ký cho phiên bản ứng dụng khách. Ứng dụng sẽ nhận được mã thông báo qua 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 thiết bị cụ thể đó, bạn cần có quyền truy cập vào mã thông báo này.

Lưu ý về tính năng 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 một thông báo, theo mặc định, thông báo sẽ không được gửi thông qua các lệnh gọi lại tích hợp của FCM. Trong trường hợp này, các phần tải tin nhắn sẽ được nhận thông qua một Intent dùng để khởi động ứng dụng. Để FCM chuyển tiếp các thông báo đến này tới lệnh gọi lại của thư viện C++, bạn cần ghi đè phương thức onNewIntent trong Hoạt động của mình và chuyển Intent vào 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);
  }
}

Các tin nhắn nhận được khi ứng dụng đang ở chế độ nền sẽ có nội dung của trường thông báo được dùng để điền vào 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
Màu nổi 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, các thông báo gửi đến ứng dụng sẽ được chuyển đến ::firebase::messaging::Listener::OnMessageReceived. Tuy nhiên, trong một số trường hợp, bạn có thể cần ghi đè hành vi mặc định. Để thực hiện 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 thông báo đến được gửi tới ứng dụng và định tuyến các thông báo đó đến thư viện C++. Khi ứng dụng chạy ở nền trước (hoặc khi ứng dụng chạy ở chế độ nền và nhận được một tải trọng chỉ bao gồm dữ liệu), các thông báo sẽ chuyể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 thao tác dựa trên đối tượng RemoteMessage đã nhận và nhận 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 vài phương thức khác ít được dùng hơn. Bạn cũng có thể ghi đè các thuộc tính 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 được viết, các lớp tuỳ chỉnh của bạn phải được đưa vào AndroidManifest.xml để có hiệu lực. Hãy đảm bảo rằng tệp kê khai có các công cụ hợp nhất 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 kho 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 và đây là cách ListenerService có thể chạy. Bạn cần thay thế ListenerService này bằng dịch vụ trình nghe cusom. 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 qua 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 (7.1.0 trở lên) sử dụng JobIntentService và cần phải 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 việc khởi chạy tự động

FCM tạo một mã thông báo đăng ký để nhắm mục tiêu theo thiết bị. Khi mã thông báo được tạo, thư viện sẽ tải dữ liệu cấu hình và giá trị nhận dạng lên Firebase. Nếu muốn được chọn sử dụng rõ ràng trước khi sử dụng mã thông báo, bạn có thể ngăn việc tạo tại thời điểm định cấu hình bằng cách tắt FCM (và trên Android, Analytics). Để thực hiện việc này, hãy thêm 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 một lệnh gọi trong thời gian chạy:

::firebase::messaging::SetTokenRegistrationOnInitEnabled(true);

Giá trị này sẽ vẫn tồn tại khi ứng dụng khởi động lại sau khi đặt.

FCM cho phép gửi thông báo chứa đường liên kết sâu đến ứng dụng của bạn. Để nhận thông báo chứa đường liên kết sâu, bạn phải thêm bộ lọc ý định mới vào hoạt động xử lý đường liên kết sâu cho ứng dụng. Bộ lọc ý định sẽ nắm bắt các đường liên kết sâu trong miền của bạn. Nếu thông báo của bạn không chứa đường liên kết sâu, thì cấu hình này là không cần thiết. 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 chứa đường liên kết đến giao thứ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 thiết lập ứng dụng, bạn có thể gửi các thông báo theo chủ đề và thông báo về sau bằng Firebase. Để tìm hiểu thêm, hãy xem chức năng này được minh hoạ trong mẫu bắt đầu 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 bạn, hãy xem hướng dẫn gửi thông báo từ máy chủ ứng dụng:

Xin lưu ý rằng bạn cần triển khai máy chủ để sử dụng các tính năng này.