Di chuyển từ API FCM cũ sang HTTP v1

Các ứng dụng sử dụng API cũ FCM không được dùng nữa cho HTTP và XMPP nên di chuyển sang API HTTP v1 trong thời gian sớm nhất. Tính năng gửi tin nhắn (bao gồm cả tin nhắn ngược dòng) bằng các API đó không còn được dùng nữa kể từ ngày 20 tháng 6 năm 2023 và sẽ bị xóa vào tháng 6 năm 2024 .

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

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

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

  • Có thể mở rộng hơn và phù hợp với tương lai hơn đối với các phiên bản nền tảng máy khách mới API HTTP v1 hỗ trợ đầy đủ các tùy chọn nhắn tin có sẵn trên nền tảng 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 nếu cần.

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

URL điểm cuối cho API HTTP v1 khác với điểm cuối cũ ở những điểm sau:

  • Nó được phiên bản, với /v1 trong đường dẫn.
  • Đường dẫn chứa ID dự án của dự án Firebase cho ứng dụng của bạn, ở định dạng /projects/myproject-ID/ . ID này có sẵn trong tab Cài đặt dự án chung của bảng điều khiển Firebase.
  • Nó chỉ định rõ ràng phương thức send:send .

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

Yêu cầu HTTP trước

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

Yêu cầu XMPP trước đây

Tin nhắn XMPP kế thừa đượ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 ủy quyền gửi yêu cầu

Thay vì chuỗi khóa máy chủ được sử dụng trong các yêu cầu cũ, yêu cầu gửi HTTP v1 yêu cầu mã thông báo truy cập OAuth 2.0. Nếu bạn đang sử dụng SDK quản trị để gửi tin nhắn 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ư được mô tả trong phần này và thêm nó 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

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

  • Thông tin xác thực mặc định của ứng dụng Google (ADC)
  • Tệp JSON của tài khoản dịch vụ
  • Mã thông báo truy cập OAuth 2.0 tồn tại trong thời gian ngắ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 Computing 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 tài khoản dịch vụ mặc định hiện có của bạn để lấy thông tin xác thực nhằm cho phép các yêu cầu và ADC cho phép thử nghiệm cục bộ linh hoạt thông qua biến môi trường GOOGLE_APPLICATION_CREDENTIALS . Để tự động hóa luồng ủy quyền tối đa, hãy sử dụng ADC cùng với các 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 xuống tệp JSON của tài khoản dịch vụ 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 để ủy quyền các yêu cầu có thông tin xác thực được lấy theo cách thủ công này. Nếu bạn 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— việc này phải được thực hiện hết sức thận trọng do có nguy cơ làm lộ thông tin xác thực 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 Google (ADC) kiểm tra thông tin xác thực của bạn theo thứ tự sau:

  1. ADC kiểm tra xem biến môi trường GOOGLE_APPLICATION_CREDENTIALS có được đặt 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ỏ tới.

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

  3. Nếu ADC không thể sử dụng một trong các thông tin xác thực trên thì hệ thống sẽ báo lỗi.

Ví dụ về mã SDK quản trị sau đây minh họa chiến lược này. Ví dụ này không chỉ định rõ ràng thông tin đăng nhập của ứng dụng. Tuy nhiên, ADC có thể ngầm tìm thấy thông tin xác thực miễn là biến môi trường được đặt hoặc miễn là ứng dụng đang chạy trên Computing 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()

Đi

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ợ các tài khoản dịch vụ của Google mà bạn có thể sử dụng để gọi API máy chủ Firebase từ máy chủ ứng dụng hoặc môi trường đáng tin cậy của mình. Nếu bạn đang phát triển mã cục bộ hoặc triển khai ứng dụng của mình tại chỗ, bạn có thể sử dụng thông tin xác thực có được thông qua tài khoản dịch vụ này để ủy quyền các yêu cầu máy chủ.

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

Để tạo tệp khóa riêng cho tài khoản dịch vụ của bạn:

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

  2. Nhấp vào Tạo khóa riêng mới , sau đó xác nhận bằng cách nhấp vào Tạo khóa .

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

Khi ủy 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 xác thực cho ứng dụng của mình. Bạn có thể đặt biến môi trường GOOGLE_APPLICATION_CREDENTIALS hoặc bạn có thể chuyển đường dẫn đến khóa tài khoản dịch vụ một cách rõ ràng trong mã. Tùy chọn đầu tiên an toàn hơn và được khuyến khích sử dụng.

Để đặ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 khóa 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"

các cửa sổ

Với PowerShell:

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

Sau khi bạn hoàn thành các bước trên, Thông tin xác thực mặc định của ứng dụng (ADC) có thể ngầm xác định thông tin xác thực của bạn, cho phép bạn sử dụng thông tin xác thực tài khoản dịch vụ khi thử nghiệm 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 để đúc mã thông báo truy cập

Sử dụng thông tin xác thực Firebase của bạn cùng với Thư viện Google Auth cho ngôn ngữ ưa thích của bạn để truy xuất mã thông báo truy cập OAuth 2.0 tồn tại trong thời gian ngắ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 khách 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 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ã thông báo 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ã thông báo truy cập đã cập nhật.

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

Để thêm mã thông báo 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 ở đị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 tải trọng thông báo JSON. Về cơ bản, những thay đổi này đảm bảo rằng tin nhắn được xử lý chính xác khi nhận được trên các nền tảng máy khách khác nhau; Ngoài ra, những thay đổi này còn giúp bạn linh hoạt hơn trong việc tùy chỉnh hoặc "ghi đè" các trường thông báo trên 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 Tùy chỉnh thông báo trên các nền tảng và xem lại tài liệu tham khảo API để làm quen với HTTP v1.

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

Dưới đây là so sánh về tải trọng thông báo rất đơn giản— chỉ chứa các trường title , bodydata thể hiện sự khác biệt cơ bản về tải trọng cũ và tải trọng HTTP v1.

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ụ: nhắm mục tiêu nhiều nền tảng

Để bật tính năng nhắm mục tiêu trên 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 khóa dành riêng cho nền tảng giúp nhà phát triển có thể thấy rõ mọi 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 mục tiêu đến nhiều nền tảng bằng một yêu cầu duy nhất, như được minh họa 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ụ: tùy chỉnh bằng tính năng ghi đè nền tảng

Ngoài việc đơn giản hóa việc nhắm mục tiêu tin nhắn trên nhiều nền tảng, API HTTP v1 còn mang đến sự linh hoạt để tùy chỉnh tin nhắn trên mỗi 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 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 của thiết bị trong khóa token thay vì khóa to .

Trước

  { "notification": {
      "body": "This is an FCM notification message!",
      "time": "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 mẫu và thông tin về API FCM HTTP v1, hãy xem phần sau: