Catch up on highlights from Firebase at Google I/O 2023. Learn more

Cho phép gửi yêu cầu

Các yêu cầu được gửi tới FCM từ máy chủ ứng dụng hoặc môi trường đáng tin cậy của bạn phải được cấp phép. Lưu ý những khác biệt quan trọng này giữa ủy quyền API HTTP cũ và HTTP v1:

  • API FCM HTTP v1 cho phép các yêu cầu bằng mã thông báo truy cập OAuth 2.0 tồn tại trong thời gian ngắn. Để đúc mã thông báo này, bạn có thể sử dụng Thông tin xác thực mặc định của ứng dụng Google (trong môi trường máy chủ của Google) và/hoặc lấy thông tin đăng nhập cần thiết theo cách thủ công từ tệp khóa riêng tư JSON được tạo cho tài khoản dịch vụ. Nếu bạn đang sử dụng SDK quản trị Firebase để gửi thư, thì thư viện sẽ xử lý mã thông báo cho bạn.
  • Các giao thức cũ chỉ có thể sử dụng các khóa API tồn tại lâu dài có được từ bảng điều khiển Firebase.

Cho phép HTTP v1 gửi yêu cầu

Tùy thuộc vào thông tin chi tiết về 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ủ cho các dịch vụ Firebase:

  • Thông tin đăng nhập 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 Compute Engine, Google Kubernetes Engine, App Engine hoặc Cloud Function (bao gồm cả Cloud Function 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 ủy quyền cho 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 hoàn toàn luồng ủy quyền, 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 cho các yêu cầu bằng các thông tin xác thực thu được theo cách thủ công này. Nếu bạn không có quyền truy cập 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 cần được thực hiện hết sức 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 bằng ADC

Thông tin đăng nhập mặc định của ứng dụng 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 GOOGLE_APPLICATION_CREDENTIALS đã được đặt chưa. 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, 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 Function 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 hai thông tin xác thực trên, thì hệ thống sẽ báo lỗi.

Ví dụ về mã SDK dành cho quản trị viên sau minh họa chiến lược này. Ví dụ này không chỉ định rõ ràng thông tin xác thực của ứng dụng. Tuy nhiên, ADC có thể 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 Compute Engine, Google Kubernetes Engine, App Engine hoặc Cloud Function.

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);

con trăn

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 xác thực theo cách thủ công

Các dự án Firebase hỗ trợ tài khoản dịch vụ 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 đăng nhập có được qua tài khoản dịch vụ này để ủy quyền cho các yêu cầu máy chủ.

Để xác thực tài khoản dịch vụ và cho phép 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 tư 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 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 rõ ràng đường dẫn đến khóa tài khoản dịch vụ trong mã. Tùy chọn đầu tiên an toàn hơn và được khuyến nghị mạnh mẽ.

Để đặ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 tất các bước trên, Thông tin đăng nhập mặc định của ứng dụng (ADC) có thể xác định hoàn toàn 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 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 đăng nhập để đúc mã thông báo truy cập

Trừ khi bạn đang sử dụng SDK quản trị , SDK tự động xử lý ủy quyền, bạn sẽ cần đúc mã thông báo truy cập và thêm mã này để gửi yêu cầu.

Sử dụng thông tin đăng nhập 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 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 .

con trăn

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.refreshAccessToken();
  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 đượ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
}

con trăn

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 " + getAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;

Cho phép giao thức kế thừa gửi yêu cầu

Với giao thức kế thừa HTTP, mỗi yêu cầu phải chứa khóa máy chủ từ tab Nhắn tin qua đám mây của ngăn Cài đặt bảng điều khiển Firebase. Đối với XMPP, bạn phải sử dụng cùng khóa máy chủ để thiết lập kết nối.

Di chuyển các khóa máy chủ kế thừa

Bắt đầu từ tháng 3 năm 2020, FCM ngừng tạo khóa máy chủ cũ. Các khóa máy chủ kế thừa hiện tại sẽ tiếp tục hoạt động nhưng chúng tôi khuyên bạn nên sử dụng phiên bản mới hơn của khóa có nhãn Khóa máy chủ trong bảng điều khiển Firebase .

Nếu muốn xóa khóa máy chủ cũ hiện có, bạn có thể thực hiện việc này trong Google Cloud Console .

Cho phép các yêu cầu HTTP

Một yêu cầu tin nhắn bao gồm hai phần: tiêu đề HTTP và phần thân HTTP. Tiêu đề HTTP phải chứa các tiêu đề sau:

  • Authorization : key=YOUR_SERVER_KEY
    Đảm bảo rằng đây là khóa máy chủ , có giá trị trong tab Nhắn tin qua đám mây của ngăn Cài đặt bảng điều khiển Firebase. FCM từ chối nền tảng Android, nền tảng Apple và trình duyệt.
  • Content-Type : application/json cho JSON; application/x-www-form-urlencoded;charset=UTF-8 cho văn bản thuần túy.
    Nếu Content-Type bị bỏ qua, định dạng được coi là văn bản thuần túy.

Ví dụ:

Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
  "data" : {
    ...
  },
}

Xem Xây dựng yêu cầu gửi để biết đầy đủ chi tiết về cách tạo yêu cầu gửi. Tham chiếu Giao thức HTTP kế thừa cung cấp danh sách tất cả các tham số mà thông báo của bạn có thể chứa.

Kiểm tra tính hợp lệ của khóa máy chủ

Nếu bạn nhận được lỗi xác thực khi gửi tin nhắn, hãy kiểm tra tính hợp lệ của khóa Máy chủ của bạn. Ví dụ: trên Linux, hãy chạy lệnh sau:

api_key=YOUR_SERVER_KEY

curl --header "Authorization: key=$api_key" \
     --header Content-Type:"application/json" \
     https://fcm.googleapis.com/fcm/send \
     -d "{\"registration_ids\":[\"ABC\"]}"

Nếu bạn nhận được mã trạng thái HTTP 401, khóa Máy chủ của bạn không hợp lệ.

Cho phép kết nối XMPP

Với XMPP, bạn có thể duy trì kết nối hai chiều, không đồng bộ, liên tục với các máy chủ FCM. Kết nối có thể được sử dụng để gửi và nhận tin nhắn giữa máy chủ của bạn và các thiết bị được kết nối FCM của người dùng.

Bạn có thể sử dụng hầu hết các thư viện XMPP để quản lý kết nối lâu dài với FCM. Điểm cuối XMPP chạy tại fcm-xmpp.googleapis.com:5235 . Khi thử nghiệm chức năng với người dùng không sản xuất, thay vào đó, bạn nên kết nối với máy chủ tiền sản xuất tại fcm-xmpp.googleapis.com:5236 (lưu ý cổng khác).

Thử nghiệm thường xuyên trong giai đoạn tiền sản xuất (một môi trường nhỏ hơn nơi các bản dựng FCM mới nhất chạy) có lợi cho việc cách ly người dùng thực khỏi mã thử nghiệm. Các thiết bị thử nghiệm và mã thử nghiệm kết nối với fcm-xmpp.googleapis.com:5236 phải sử dụng ID người gửi FCM khác để tránh mọi rủi ro khi gửi tin nhắn thử nghiệm tới người dùng sản xuất hoặc gửi tin nhắn ngược dòng từ lưu lượng sản xuất qua các kết nối thử nghiệm.

Kết nối có hai yêu cầu quan trọng:

  • Bạn phải bắt đầu kết nối Bảo mật tầng vận chuyển (TLS). Lưu ý rằng FCM hiện không hỗ trợ tiện ích mở rộng STARTTLS .
  • FCM yêu cầu cơ chế xác thực SASL PLAIN sử dụng <your_FCM_Sender_Id>@fcm.googleapis.com ( ID người gửi FCM ) và khóa Máy chủ làm mật khẩu. Các giá trị này có sẵn trong tab Nhắn tin qua đám mây của ngăn Cài đặt bảng điều khiển Firebase.

Nếu tại bất kỳ thời điểm nào kết nối không thành công, bạn nên kết nối lại ngay lập tức. Không cần phải lùi lại sau khi ngắt kết nối xảy ra sau khi xác thực. Đối với mỗi ID người gửi , FCM cho phép 2500 kết nối song song.

Đoạn mã sau minh họa cách thực hiện xác thực và ủy quyền cho kết nối XMPP với FCM.

máy chủ XMPP

Máy chủ XMPP yêu cầu kết nối với FCM

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

FCM mở kết nối và yêu cầu cơ chế xác thực, bao gồm phương thức PLAIN .

<stream:features>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>X-OAUTH2</mechanism>
    <mechanism>X-GOOGLE-TOKEN</mechanism>
    <mechanism>PLAIN</mechanism>
  </mechanisms>
</stream:features>

máy chủ XMPP

Máy chủ XMPP phải phản hồi bằng phương pháp xác thực PLAIN , cung cấp khóa máy chủ từ tab Nhắn tin qua đám mây của ngăn Cài đặt bảng điều khiển Firebase.

<auth mechanism="PLAIN"
xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb
mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth>

FCM

<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

máy chủ XMPP

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

<stream:features>
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</stream:features>

máy chủ XMPP

<iq type="set">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"></bind>
</iq>

FCM

<iq type="result">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <jid>SENDER_ID@fcm.googleapis.com/RESOURCE</jid>
  </bind>
</iq>

Lưu ý: FCM không sử dụng tài nguyên bị ràng buộc trong khi định tuyến thư.

Xem Xây dựng yêu cầu gửi để biết đầy đủ chi tiết về cách tạo yêu cầu gửi. Legacy XMPP Protocol Reference cung cấp danh sách tất cả các tham số mà thông báo của bạn có thể chứa.