Các ứng dụng sử dụng API FCM cũ không được dùng nữa cho HTTP và XMPP nên chuyển sang API HTTP phiên bản 1 trong thời gian sớm nhất có thể. Việc gửi tin nhắn (bao gồm cả tin nhắn ngược dòng) bằng những API đó đã ngừng hoạt động từ ngày 20 tháng 6 năm 2023 và quá trình ngừng hoạt động sẽ 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 việc hỗ trợ liên tục và các tính năng mới, HTTP v1 API còn có những ưu điểm sau so với các API cũ:
Tăng cường bảo mật thông qua mã truy cập API HTTP phiên bản 1 sử dụng mã truy cập có thời hạn ngắn theo mô hình bảo mật OAuth2. Trong trường hợp mã truy cập bị lộ, mã này chỉ có thể bị sử dụng cho mục đích xấu trong khoảng một giờ trước khi hết hạn. Mã làm mới không được truyền thường xuyên như các khoá bảo mật được dùng trong API cũ, nên ít có khả năng bị thu thập hơn nhiều.
Tuỳ chỉnh thông báo hiệu quả hơn trên nhiều nền tảng Đối với nội dung thông báo, HTTP v1 API có các khoá chung cho tất cả các phiên bản được nhắm đến, cộng với các khoá dành riêng cho nền tảng cho phép bạn tuỳ chỉnh thông báo trên nhiều nền tảng. Điều này cho phép bạn tạo "ghi đè" để gửi các tải trọng hơi khác nhau đến các nền tảng ứng dụng khách khác nhau trong một thông báo duy nhất.
Có khả năng mở rộng hơn và đảm bảo khả năng tương thích với các phiên bản nền tảng máy khách mới trong tương lai API HTTP phiên bản 1 hỗ trợ đầy đủ các lựa chọn nhắn tin có trên các nền tảng của Apple, Android và Web. Vì mỗi nền tảng có khối được xác định riêng trong tải trọng JSON, nên FCM có thể mở rộng API sang 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 cho HTTP API phiên bản 1 khác với điểm cuối cũ ở những điểm sau:
- API này được phân phiên bản, với
/v1
trong đường dẫn. - Đường dẫn này 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ã nhận dạng này có trong thẻ Cài đặt chung của dự án trên bảng điều khiển Firebase. - Thao tác này chỉ định rõ phương thức
send
là: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 tiêu đề của yêu cầu gửi.
Yêu cầu HTTP trước
POST https://fcm.googleapis.com/fcm/send
Yêu cầu XMPP trước khi thay đổi
Thông báo XMPP cũ được gửi qua một 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 việc uỷ quyền gửi yêu cầu
Thay cho chuỗi khoá máy chủ được dùng trong các yêu cầu cũ, yêu cầu gửi HTTP phiên bản 1 cần có mã truy cập OAuth 2.0. Nếu bạn đang sử dụng Admin SDK để gửi thông báo, thì 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ư mô tả trong phần này và thêm mã thông báo đó vào tiêu đề dưới dạng 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 về môi trường máy chủ của bạn, hãy kết hợp các chiến lược này để cho phép các yêu cầu của máy chủ đối với các dịch vụ Firebase:
- Thông tin xác thực mặc định của ứng dụng (ADC) trên Google
- Tệp JSON tài khoản dịch vụ
- Mã truy cập OAuth 2.0 có thời hạn ngắn bắt nguồn từ mộ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 cả Cloud Functions for Firebase), hãy sử dụng Thông tin đăng nhập mặc định của ứng dụng (ADC). ADC sử dụng tài khoản dịch vụ mặc định hiện có của bạn để lấy thông tin đăng nhập nhằm uỷ quyền cho các yêu cầu và ADC cho phép kiểm thử linh hoạt trên máy thông qua biến môi trường GOOGLE_APPLICATION_CREDENTIALS. Để tự động hoá hoàn toàn quy trình uỷ quyền, hãy sử dụng ADC cùng với các thư viện máy chủ Admin SDK.
Nếu ứng dụng của bạn đang chạy trên một môi trường máy chủ không phải của Google, bạn cần tải tệp JSON 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 một hệ thống tệp chứa tệp khoá riêng tư, bạn có thể sử dụng biến môi trường GOOGLE_APPLICATION_CREDENTIALS để uỷ quyền các yêu cầu bằng những thông tin đăng nhập thu được theo cách thủ công này. Nếu không có quyền truy cập vào tệp như vậy, bạn phải tham chiếu tệp tài khoản dịch vụ trong mã của mình. Bạn phải thực hiện việc này một cách hết sức cẩn thận do nguy cơ để lộ thông tin đăng nhập của bạn.
Cung cấp thông tin xác thực bằng ADC
Thông tin xác thực mặc định của ứng dụng trên Google (ADC) sẽ kiểm tra thông tin xác thực của bạn theo thứ tự sau:
ADC kiểm tra xem biến môi trường GOOGLE_APPLICATION_CREDENTIALS có được thiết lập hay không. Nếu biến được đặt, ADC sẽ sử dụng tệp tài khoản dịch vụ mà biến đó trỏ đến.
Nếu biến môi trường chưa được đặt, thì ADC sẽ sử dụng tài khoản dịch vụ mặc định mà Compute Engine, Google Kubernetes Engine, App Engine và Cloud Functions cung cấp cho các ứng dụng chạy trên những dịch vụ đó.
Nếu ADC không thể sử dụng một trong hai thông tin đăng nhập trên, hệ thống sẽ báo lỗi.
Ví dụ về mã Admin SDK sau đây minh hoạ chiến lược này. Ví dụ này không chỉ định rõ thông tin xác thực ứng dụng. Tuy nhiên, ADC có thể tìm thấy thông tin đăng nhập một cách ngầm định miễn là bạn đặt biến môi trường 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()
Tìm
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ợ tài khoản dịch vụ của Google. Bạn có thể dùng tài khoản này để gọi API máy chủ Firebase từ máy chủ ứng dụng hoặc môi trường đáng tin cậy. Nếu đang phát triển mã 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 nhận được thông qua tài khoản dịch vụ này để uỷ quyền cho các yêu cầu của máy chủ.
Để xác thực tài khoản dịch vụ và uỷ quyền cho tài khoản đó truy cập vào 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ụ:
Trong bảng điều khiển Firebase, hãy mở Settings > Service Accounts (Cài đặt > Tài khoản dịch vụ).
Nhấp vào Tạo khoá riêng tư mới, rồi xác nhận bằng cách nhấp vào Tạo khoá.
Lưu trữ an toàn tệp JSON chứa khoá.
Khi uỷ quyền thông qua tài khoản dịch vụ, bạn có hai lựa chọn để cung cấp thông tin đăng nhập cho ứng dụng của mình. Bạn có thể đặt biến môi trường GOOGLE_APPLICATION_CREDENTIALS hoặc truyền rõ ràng đường dẫn đến khoá tài khoản dịch vụ trong mã. Lựa chọn đầu tiên an toàn hơn và bạn nên dùng.
Cách đặt biến môi trường:
Đặt biến môi trường GOOGLE_APPLICATION_CREDENTIALS thành đường dẫn tệp của tệp JSON chứa khoá tài khoản dịch vụ. Biến này chỉ áp dụng cho phiên shell hiện tại, 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, Application Default Credentials (ADC) (Thông tin đăng nhập mặc định của ứng dụng) có thể xác định ngầm thông tin đăng nhập của bạn, cho phép bạn sử dụng thông tin đăng nhập tài khoản dịch vụ khi kiểm thử hoặc chạy trong môi trường không phải của Google.
Sử dụng thông tin xác thực để tạo mã truy cập
Sử dụng thông tin đăng nhập Firebase cùng với Thư viện xác thực của Google cho ngôn ngữ bạn muốn để truy xuất mã truy cập OAuth 2.0 có thời hạn ngắn:
node.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 Google API xác thực yêu cầu bằng mã thông báo web JSON hoặc JWT. Để biết thêm thông tin, hãy xem phần 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 hết hạn, phương thức làm mới mã thông báo sẽ tự động được gọi để truy xuất mã truy cập mới.
Để cho phép truy cập vào FCM, hãy yêu cầu phạm vi https://www.googleapis.com/auth/firebase.messaging
.
Cách thêm mã truy cập vào tiêu đề yêu cầu HTTP:
Thêm mã thông báo làm giá trị của tiêu đề Authorization
theo định dạng Authorization: Bearer <access_token>
:
node.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 phiên bản 1 có một thay đổi đáng kể trong việc cấu trúc tải trọng thông báo JSON. Những thay đổi này chủ yếu nhằm đảm bảo rằng các thông báo được xử lý chính xác khi nhận được trên các nền tảng ứng dụng khác nhau; ngoài ra, những thay đổi này mang lại cho bạn sự linh hoạt hơn để tuỳ chỉnh hoặc "ghi đè" các trường thông báo theo từng nền tảng.
Ngoài việc kiểm tra các ví dụ trong phần này, hãy xem bài viết Tuỳ chỉnh thông báo trên nhiều nền tảng và xem tài liệu tham khảo API để làm quen với HTTP phiên bản 1.
Ví dụ: thông báo đơn giản
Dưới đây là nội dung thông báo rất đơn giản (chỉ chứa các trường title
, body
và data
) minh hoạ những điểm khác biệt cơ bản trong nội dung cũ và nội dung 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 nhau
Không giống như API nhắn tin cũ, HTTP v1 API không hỗ trợ các giá trị JSON lồng nhau trong trường data
.
Bạn cần chuyển đổi từ JSON sang chuỗi.
Trước
{
...
"data": {
"keysandvalues": {"key1": "value1", "key2": 123}
}
}
Sau
{
"message": {
...
"data": {
"keysandvalues": "{\"key1\": \"value1\", \"key2\": 123}"
}
}
}
Ví dụ: nhắm đến nhiều nền tảng
Để bật tính năng nhắm đến nhiều nền tảng, API cũ đã thực hiện các chế độ ghi đè ở phần phụ trợ. Ngược lại, HTTP phiên bản 1 cung cấp các khối khoá dành riêng cho nền tảng, giúp nhà phát triển thấy rõ mọi điểm khác biệt giữa các nền tảng. Điều này cho phép bạn luôn nhắm đến nhiều nền tảng bằng một yêu cầu duy nhất, như 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ác chế độ ghi đè nền tảng
Ngoài việc đơn giản hoá việc nhắm đến nhiều nền tảng của thông báo, HTTP v1 API còn mang đến sự linh hoạt để tuỳ chỉnh thông báo cho từng nền tảng.
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 đến các thiết bị cụ thể
Để nhắm đến các thiết bị cụ thể bằng HTTP v1 API, hãy cung cấp mã thông báo đăng ký hiện tại của thiết bị 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ề API HTTP v1 FCM, hãy xem những nội dung sau:
Hướng dẫn về cách tạo yêu cầu gửi của máy chủ ứng dụng bằng HTTP API phiên bản 1. Tất cả đoạn mã "REST" đều sử dụng API phiên bản 1, trừ phi có ghi chú cụ thể.