Di chuyển từ API FCM cũ sang HTTP phiên bản 1

Các ứng dụng đang dùng API cũ FCM không dùng nữa cho HTTP và XMPP nên chuyển sang API HTTP v1 trong thời gian sớm nhất có thể. Đang gửi tin nhắn (bao gồm cả các thông báo ngược dòng) với những API đó không được dùng nữa vào Ngày 20 tháng 6 năm 2023 và thời gian ngừng hoạt động bắt đầu từ ngày 22 tháng 7 năm 2024.

Tìm hiểu thêm về các tính năng cụ thể bị ảnh hưởng.

Ngoài hỗ trợ liên tục và các tính năng mới, API HTTP v1 có những ưu điểm này so với các API cũ:

  • Bảo mật tốt hơn qua mã truy cập API HTTP v1 sử dụng quyền truy cập ngắn hạn mã theo mô hình bảo mật OAuth2. Trong trường hợp mã truy cập sẽ được công khai, mã này chỉ có thể được dùng cho mục đích xấu trong khoảng một giờ trước hết hạn. Mã làm mới không được truyền thường xuyên như khoá bảo mật được dùng trong API cũ, nên chúng ít có khả năng được ghi lại.

  • Tuỳ chỉnh thông báo hiệu quả hơn trên nhiều nền tảng Đối với thông báo nội dung, API HTTP v1 có các khoá chung truy cập vào tất cả các thực thể được nhắm mục tiêu, cùng với các khoá dành riêng cho nền tảng giúp bạn tuỳ chỉnh thông điệp trên nhiều nền tảng. Điều này cho phép bạn tạo nội dung "ghi đè" gửi các tải trọng hơi khác nhau đến nền tảng khách hàng trong một thông điệp duy nhất.

  • Các phiên bản nền tảng ứng dụng mới, dễ mở rộng hơn và phù hợp với tương lai API HTTP v1 hỗ trợ đầy đủ các tuỳ chọn nhắn tin có sẵn trên nền tảng của Apple, Android và Web. Vì mỗi nền tảng có khối riêng được xác định trong tải trọng JSON, FCM có thể mở rộng API cho các phiên bản mới và nền tảng mới khi cần.

Cập nhật điểm cuối của máy chủ

URL điểm cuối của API HTTP v1 khác với điểm cuối cũ ở cách:

  • Đã tạo phiên bản, với /v1 trong đường dẫn.
  • Đường dẫn chứa mã dự án của dự án Firebase cho ứng dụng của bạn, ở định dạng /projects/myproject-ID/. Mã này có bằng thẻ General project settings (Cài đặt dự án chung) bảng điều khiển của Firebase.
  • Tham số này chỉ định rõ phương thức send:send.

Để cập nhật điểm cuối của máy chủ cho HTTP phiên bản 1, hãy thêm các phần tử này vào điểm cuối trong phần tiêu đề của yêu cầu gửi.

Các yêu cầu HTTP trước đó

POST https://fcm.googleapis.com/fcm/send

Các yêu cầu XMPP trước đó

Thông báo XMPP cũ được gửi qua kết nối đến điểm cuối sau:

fcm-xmpp.googleapis.com:5235

Sau

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send

Cập nhật trạng thái cho phép gửi yêu cầu

Thay cho chuỗi khoá máy chủ dùng trong các yêu cầu cũ, HTTP v1 sẽ gửi yêu cầu cần có mã truy cập OAuth 2.0. Nếu bạn đang dùng SDK dành cho quản trị viên để gửi thông báo, thư viện sẽ xử lý mã thông báo cho bạn. Nếu bạn đang sử dụng giao thức thô, hãy lấy mã thông báo như được mô tả trong phần này và thêm mã đó vào tiêu đề là Authorization: Bearer <valid Oauth 2.0 token>.

Trước

Authorization: key=AIzaSyZ-1u...0GBYzPu7Udno5aA

Sau

Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

Tuỳ thuộc vào thông tin chi tiết của môi trường máy chủ, hãy sử dụng kết hợp các chiến lược này để cấp quyền cho máy chủ các yêu cầu đến dịch vụ Firebase:

  • Thông tin xác thực mặc định của ứng dụng trên Google (ADC)
  • Tệp JSON của tài khoản dịch vụ
  • Mã truy cập OAuth 2.0 ngắn hạn được lấy từ tài khoản dịch vụ

Nếu ứng dụng của bạn đang chạy trên Compute Engine, Google Kubernetes Engine, App Engine hoặc Cloud Functions (bao gồm Cloud Functions cho Firebase), hãy sử dụng Thông tin xác thực mặc định của ứng dụng (ADC). ADC sử dụng dịch vụ mặc định hiện có của bạn tài khoản của bạn để lấy thông tin đăng nhập để ủy quyền cho các yêu cầu và ADC cho phép kiểm thử cục bộ linh hoạt thông qua biến môi trường GOOGLE_APPLICATION_CREDENTIALS. Để tự động hoá tối đa quy trình uỷ quyền, hãy sử dụng ADC cùng với thư viện máy chủ SDK dành cho quản trị viên.

Nếu ứng dụng của bạn đang chạy trên môi trường máy chủ không phải của Google, bạn sẽ cần tải tệp JSON của tài khoản dịch vụ xuống từ dự án Firebase của mình. Miễn là bạn có quyền truy cập vào hệ thống tệp chứa tệp khóa riêng tư, bạn có thể sử dụng biến môi trường GOOGLE_APPLICATION_CREDENTIALS để cho phép các yêu cầu bằng các thông tin xác thực được thu thập theo cách thủ công này. Nếu bạn thiếu quyền truy cập tệp đó, bạn phải tham chiếu tệp tài khoản dịch vụ trong mã của mình— Việc này nên được thực hiện thật cẩn thận do có nguy cơ làm lộ thông tin đăng nhập của bạn.

Cung cấp thông tin đăng nhập qua ADC

Thông tin đăng nhập mặc định của ứng dụng trên Google (ADC) kiểm tra thông tin đăng nhập của bạn theo thứ tự sau:

  1. ADC kiểm tra xem biến môi trường Đã đặt GOOGLE_APPLICATION_CREDENTIALS. Nếu biến được đặt, ADC sử dụng tệp tài khoản dịch vụ mà biến trỏ đến.

  2. Nếu bạn không đặt biến môi trường, ADC sẽ sử dụng tài khoản dịch vụ mặc định Compute Engine, Google Kubernetes Engine, App Engine, và Cloud Functions cung cấp các ứng dụng chạy trên các dịch vụ đó.

  3. Nếu ADC không thể sử dụng thông tin đăng nhập nào ở trên, thì hệ thống sẽ gửi thông báo lỗi.

Ví dụ về mã SDK dành cho quản trị viên sau đây minh hoạ chiến lược này. Ví dụ không chỉ định rõ ràng thông tin xác thực ứng dụng. Tuy nhiên, ADC có thể ngầm tìm thông tin đăng nhập miễn là biến môi trường được thiết lập, hoặc miễn là ứng dụng đang chạy trên Compute Engine, Google Kubernetes Engine, App Engine hoặc Cloud Functions.

Node.js

admin.initializeApp({
  credential: admin.credential.applicationDefault(),
});

Java

FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
    .build();

FirebaseApp.initializeApp(options);

Python

default_app = firebase_admin.initialize_app()

Tiến hành

app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

C#

FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
});

Cung cấp thông tin đăng nhập theo cách thủ công

Các dự án Firebase hỗ trợ Google tài khoản dịch vụ, mà bạn có thể dùng để gọi Firebase từ máy chủ ứng dụng hoặc môi trường đáng tin cậy. Nếu bạn đang phát triển lập trình cục bộ hoặc triển khai ứng dụng tại chỗ, bạn có thể sử dụng thông tin đăng nhập có được thông qua tài khoản dịch vụ này để uỷ quyền cho các yêu cầu máy chủ.

Để xác thực tài khoản dịch vụ và uỷ quyền tài khoản đó để truy cập các dịch vụ của Firebase, bạn phải tạo một tệp khoá riêng tư ở định dạng JSON .

Cách tạo tệp khoá riêng tư cho tài khoản dịch vụ:

  1. Trong bảng điều khiển của Firebase, hãy mở Cài đặt > Tài khoản dịch vụ.

  2. Nhấp vào Generate New Private Key (Tạo khoá riêng tư mới), sau đó xác nhận bằng cách nhấp vào Generate key (Tạo khoá).

  3. Lưu trữ an toàn tệp JSON chứa khoá.

Khi uỷ quyền qua tài khoản dịch vụ, bạn có hai lựa chọn để cung cấp vào ứng dụng của bạn. Bạn có thể đặt GOOGLE_APPLICATION_CREDENTIALS biến môi trường, hoặc bạn có thể chuyển đường dẫn đến khoá tài khoản dịch vụ trong mã một cách rõ ràng. Lựa chọn đầu tiên an toàn hơn và được khuyên dùng.

Cách đặt biến môi trường:

Đặt biến môi trường GOOGLE_APPLICATION_CREDENTIALS vào đường dẫn tệp của tệp JSON chứa khoá tài khoản dịch vụ của bạn. Biến này chỉ áp dụng cho phiên shell hiện tại của bạn, vì vậy nếu bạn mở một phiên mới, hãy đặt lại biến.

Linux hoặc macOS

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

Windows

Với PowerShell:

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"

Sau khi bạn hoàn tất các bước trên, Thông tin xác thực mặc định của ứng dụng (ADC) có thể xác định một cách ngầm ẩn các thông tin xác thực của bạn, cho phép bạn sử dụng dịch vụ thông tin đăng nhập tài khoản khi thử nghiệm hoặc chạy trong các môi trường không phải của Google.

Dùng thông tin xác thực để đúc mã truy cập

Sử dụng thông tin đăng nhập Firebase của bạn cùng với Thư viện xác thực của Google cho ngôn ngữ bạn muốn dùng để truy xuất mã truy cập OAuth 2.0 ngắn hạn:

nút.js

 function getAccessToken() {
  return new Promise(function(resolve, reject) {
    const key = require('../placeholders/service-account.json');
    const jwtClient = new google.auth.JWT(
      key.client_email,
      null,
      key.private_key,
      SCOPES,
      null
    );
    jwtClient.authorize(function(err, tokens) {
      if (err) {
        reject(err);
        return;
      }
      resolve(tokens.access_token);
    });
  });
}

Trong ví dụ này, thư viện ứng dụng API của Google sẽ xác thực yêu cầu bằng mã thông báo web JSON hay JWT. Để biết thêm thông tin, hãy xem Mã thông báo web JSON.

Python

def _get_access_token():
  """Retrieve a valid access token that can be used to authorize requests.

  :return: Access token.
  """
  credentials = service_account.Credentials.from_service_account_file(
    'service-account.json', scopes=SCOPES)
  request = google.auth.transport.requests.Request()
  credentials.refresh(request)
  return credentials.token

Java

private static String getAccessToken() throws IOException {
  GoogleCredentials googleCredentials = GoogleCredentials
          .fromStream(new FileInputStream("service-account.json"))
          .createScoped(Arrays.asList(SCOPES));
  googleCredentials.refresh();
  return googleCredentials.getAccessToken().getTokenValue();
}

Sau khi mã truy cập của bạn hết hạn, phương thức làm mới mã thông báo sẽ được gọi để tự động truy xuất mã truy cập đã cập nhật.

Để cấp quyền truy cập vào FCM, hãy yêu cầu cấp phạm vi https://www.googleapis.com/auth/firebase.messaging.

Cách thêm mã truy cập vào tiêu đề của yêu cầu HTTP:

Thêm mã thông báo dưới dạng giá trị của tiêu đề Authorization theo định dạng Authorization: Bearer <access_token>:

nút.js

headers: {
  'Authorization': 'Bearer ' + accessToken
}

Python

headers = {
  'Authorization': 'Bearer ' + _get_access_token(),
  'Content-Type': 'application/json; UTF-8',
}

Java

URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getServiceAccountAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;

Cập nhật tải trọng của yêu cầu gửi

FCM HTTP v1 giới thiệu một thay đổi đáng kể trong cấu trúc của thông báo JSON tải trọng. Trước hết, những thay đổi này giúp đảm bảo rằng các thư được xử lý chính xác khi nhận được trên các nền tảng khách hàng khác nhau; ngoài ra, những thay đổi này sẽ cung cấp cho bạn linh hoạt hơn để tùy chỉnh hoặc "ghi đè" trường thông báo cho mỗi nền tảng.

Ngoài việc kiểm tra các ví dụ trong phần này, hãy xem Tuỳ chỉnh thông điệp trên các nền tảng và xem xét Tài liệu tham khảo API để nhận được quen thuộc với HTTP phiên bản 1.

Ví dụ: tin nhắn thông báo đơn giản

Sau đây là thông tin so sánh về một tải trọng thông báo rất đơn giản — chứa Chỉ các trường title, bodydata – thể hiện kiến thức cơ bản về sự khác biệt trong các tải trọng cũ và HTTP phiên bản 1.

Trước

{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available."
  },
  "data": {
    "story_id": "story_12345"
  }
}

Sau

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    }
  }
}

Ví dụ: dữ liệu JSON lồng ghép

Không giống như API thông báo cũ, API HTTP phiên bản 1 không hỗ trợ các giá trị JSON lồng nhau trong trường data. Bạn phải chuyển đổi từ JSON thành chuỗi.

Trước

{
  ...
  "data": {
    "keysandvalues": {"key1": "value1", "key2": 123}
  }
}

Sau

{
  "message": {
   ...
    "data": {
      "keysandvalues": "{\"key1\": \"value1\", \"key2\": 123}"
    }
  }
}

Ví dụ: nhắm mục tiêu nhiều nền tảng

Để cho phép nhắm mục tiêu nhiều nền tảng, API cũ đã thực hiện ghi đè trong phần phụ trợ. Ngược lại, HTTP v1 cung cấp các khối khoá dành riêng cho từng nền tảng tạo ra bất kỳ sự khác biệt nào giữa các nền tảng phản cảm và nhà phát triển thấy được. Điều này cho phép bạn nhắm mục tiêu nhiều luôn có một yêu cầu duy nhất, như được minh hoạ trong mẫu sau.

Trước

// Android
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "TOP_STORY_ACTIVITY"
  },
  "data": {
    "story_id": "story_12345"
  }
}
// Apple
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "HANDLE_BREAKING_NEWS"
  },
  "data": {
    "story_id": "story_12345"
  }
}

Sau

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    },
    "android": {
      "notification": {
        "click_action": "TOP_STORY_ACTIVITY"
      }
    },
    "apns": {
      "payload": {
        "aps": {
          "category" : "NEW_MESSAGE_CATEGORY"
        }
      }
    }
  }
}

Ví dụ: tuỳ chỉnh bằng cơ chế ghi đè nền tảng

Ngoài việc đơn giản hoá việc nhắm mục tiêu thông báo trên nhiều nền tảng, API HTTP v1 cho phép bạn tuỳ chỉnh thông điệp theo từng nền tảng một cách linh hoạt.

Trước

// Android
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "Check out the Top Story.",
    "click_action": "TOP_STORY_ACTIVITY"
  },
  "data": {
    "story_id": "story_12345"
  }
}
// Apple
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "HANDLE_BREAKING_NEWS"
  },
  "data": {
    "story_id": "story_12345"
  }
}

Sau

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    },
    "android": {
      "notification": {
        "click_action": "TOP_STORY_ACTIVITY",
        "body": "Check out the Top Story"
      }
    },
    "apns": {
      "payload": {
        "aps": {
          "category" : "NEW_MESSAGE_CATEGORY"
        }
      }
    }
  }
}

Ví dụ: nhắm mục tiêu các thiết bị cụ thể

Để nhắm mục tiêu các thiết bị cụ thể bằng API HTTP v1, hãy cung cấp mã thông báo đăng ký hiện tại trong khoá token thay vì khoá to.

Trước

  { "notification": {
      "body": "This is an FCM notification message!",
      "title": "FCM Message"
    },
    "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
  }

Sau

{
   "message":{
      "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
      "notification":{
        "body":"This is an FCM notification message!",
        "title":"FCM Message"
      }
   }
}

Để biết thêm các mẫu và thông tin về FCM HTTP v1 API, hãy xem các nội dung sau: