Firebase is back at Google I/O on May 10! Register now
Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

Môi trường máy chủ của bạn và FCM

Phía máy chủ của Firebase Cloud Messaging bao gồm hai thành phần:

  • Chương trình phụ trợ FCM do Google cung cấp.
  • Máy chủ ứng dụng của bạn hoặc môi trường máy chủ đáng tin cậy khác nơi logic máy chủ của bạn chạy, chẳng hạn như Chức năng đám mây cho Firebase hoặc các môi trường đám mây khác do Google quản lý.

Máy chủ ứng dụng hoặc môi trường máy chủ đáng tin cậy của bạn sẽ gửi các yêu cầu tin nhắn đến phần phụ trợ FCM, sau đó sẽ định tuyến các tin nhắn đến các ứng dụng khách đang chạy trên thiết bị của người dùng.

Yêu cầu đối với môi trường máy chủ đáng tin cậy

Môi trường máy chủ ứng dụng của bạn phải đáp ứng các tiêu chí sau:

  • Có thể gửi các yêu cầu tin nhắn được định dạng đúng đến phụ trợ FCM.
  • Có thể xử lý các yêu cầu và gửi lại chúng bằng cách sử dụng tính năng rút lui theo cấp số nhân.
  • Có thể lưu trữ an toàn thông tin xác thực ủy quyền máy chủ và mã thông báo đăng ký ứng dụng khách.
  • Đối với giao thức XMPP (nếu được sử dụng), máy chủ phải có khả năng tạo ID tin nhắn để nhận dạng duy nhất từng tin nhắn nó gửi (phần phụ trợ FCM HTTP tạo ID tin nhắn và trả lại chúng trong phản hồi). ID tin nhắn XMPP phải là duy nhất cho mỗi ID người gửi.

Chọn tùy chọn máy chủ

Bạn sẽ cần quyết định cách tương tác với máy chủ FCM: sử dụng SDK quản trị Firebase hoặc giao thức thô. Do khả năng hỗ trợ trên các ngôn ngữ lập trình phổ biến và các phương pháp thuận tiện để xử lý xác thực và ủy quyền, SDK quản trị Firebase là phương pháp được đề xuất.

Các tùy chọn để tương tác với máy chủ FCM bao gồm:

  • SDK quản trị Firebase, có hỗ trợ cho Node , Java , Python , C#Go .
  • API FCM HTTP v1 , là tùy chọn giao thức cập nhật nhất, với khả năng ủy quyền an toàn hơn và nhắn tin đa nền tảng linh hoạt (SDK quản trị Firebase dựa trên giao thức này và cung cấp tất cả các lợi thế vốn có của nó). Vì các tính năng mới thường chỉ được thêm vào API HTTP v1, chúng tôi khuyên bạn nên sử dụng API này cho hầu hết các trường hợp sử dụng.
  • Giao thức HTTP kế thừa . Các dự án mới được khuyến nghị áp dụng API HTTP FCM v1 thay vì giao thức cũ.
  • Giao thức máy chủ XMPP kế thừa . Các dự án mới được khuyến nghị áp dụng API HTTP FCM v1 thay vì giao thức cũ.

SDK quản trị Firebase cho FCM

API FCM dành cho quản trị viên xử lý xác thực với chương trình phụ trợ và tạo điều kiện gửi tin nhắn cũng như quản lý đăng ký chủ đề. Với SDK quản trị Firebase, bạn có thể:

  • Gửi tin nhắn đến các thiết bị cá nhân
  • Gửi tin nhắn đến các chủ đề và câu điều kiện phù hợp với một hoặc nhiều chủ đề.
  • Đăng ký và hủy đăng ký thiết bị đến và từ các chủ đề
  • Xây dựng tải trọng tin nhắn phù hợp với các nền tảng mục tiêu khác nhau

SDK Node.js dành cho quản trị viên cung cấp các phương thức gửi tin nhắn đến các nhóm thiết bị.

Để thiết lập SDK quản trị Firebase, hãy xem Thêm SDK quản trị Firebase vào máy chủ của bạn . Nếu bạn đã có dự án Firebase, hãy bắt đầu với Thêm SDK . Ngoài ra, hãy đảm bảo bật API Cloud Messagin trong trang cài đặt Cloud Messaging cho dự án của bạn. Sau đó, khi SDK quản trị Firebase được cài đặt, bạn có thể bắt đầu viết logic để tạo yêu cầu gửi .

Giao thức máy chủ FCM

Hiện tại FCM cung cấp các giao thức máy chủ thô này:

Máy chủ ứng dụng của bạn có thể sử dụng các giao thức này một cách riêng biệt hoặc song song. Bởi vì đây là phiên bản cập nhật nhất và linh hoạt nhất để gửi tin nhắn đến nhiều nền tảng, API FCM HTTP v1 được khuyên dùng ở bất kỳ nơi nào khả thi. Nếu yêu cầu của bạn bao gồm nhắn tin ngược dòng từ thiết bị đến máy chủ, bạn sẽ cần triển khai giao thức XMPP.

Tin nhắn XMPP khác với tin nhắn HTTP theo các cách sau:

  • Tin nhắn ngược dòng/hạ lưu
    • HTTP: Chỉ xuôi dòng, từ đám mây đến thiết bị.
    • XMPP: Thượng nguồn và hạ lưu (thiết bị tới đám mây, đám mây tới thiết bị).
  • Nhắn tin (đồng bộ hoặc không đồng bộ)
    • HTTP: Đồng bộ. Máy chủ ứng dụng gửi tin nhắn dưới dạng yêu cầu HTTP POST và chờ phản hồi. Cơ chế này là đồng bộ và chặn người gửi gửi một tin nhắn khác cho đến khi nhận được phản hồi.
    • XMPP: Không đồng bộ. Máy chủ ứng dụng gửi/nhận tin nhắn đến/từ tất cả các thiết bị của họ ở tốc độ tối đa trên các kết nối XMPP liên tục. Máy chủ kết nối XMPP gửi xác nhận hoặc thông báo lỗi (ở dạng thông báo XMPP được mã hóa JSON ACK và NACK đặc biệt) không đồng bộ.
  • JSON
    • HTTP: Tin nhắn JSON được gửi dưới dạng HTTP POST.
    • XMPP: Thông báo JSON được gói gọn trong thông báo XMPP.
  • Văn bản thô
    • HTTP: Tin nhắn văn bản thuần túy được gửi dưới dạng HTTP POST.
    • XMPP: Không được hỗ trợ.
  • Phát đa hướng xuôi dòng gửi tới nhiều mã thông báo đăng ký.
    • HTTP: Được hỗ trợ ở định dạng tin nhắn JSON.
    • XMPP: Không được hỗ trợ.

Triển khai giao thức máy chủ HTTP

Để gửi tin nhắn, máy chủ ứng dụng đưa ra yêu cầu POST với tiêu đề HTTP và nội dung HTTP bao gồm các cặp giá trị khóa JSON. Để biết chi tiết về các tùy chọn tiêu đề và nội dung, hãy xem Xây dựng yêu cầu gửi máy chủ ứng dụng

Triển khai giao thức máy chủ XMPP

Tải trọng JSON cho tin nhắn FCM tương tự như giao thức HTTP, với những ngoại lệ sau:

  • Không có hỗ trợ cho nhiều người nhận.
  • FCM thêm trường message_id , trường này là bắt buộc. ID này xác định duy nhất thông báo trong kết nối XMPP. ACK hoặc NACK từ FCM sử dụng message_id để xác định một tin nhắn được gửi từ máy chủ ứng dụng đến FCM. Do đó, điều quan trọng là message_id này không chỉ là duy nhất (trên mỗi ID người gửi ) mà còn phải luôn hiện diện.
  • XMPP sử dụng khóa máy chủ để cho phép kết nối liên tục với FCM. Xem Cho phép gửi yêu cầu để biết thêm thông tin.

Ngoài các thông báo FCM thông thường, các thông báo điều khiển được gửi, được biểu thị bằng trường message_type trong đối tượng JSON. Giá trị có thể là 'ack' hoặc 'nack' hoặc 'control' (xem các định dạng bên dưới). Bất kỳ tin nhắn FCM nào có message_type không xác định đều có thể bị máy chủ của bạn bỏ qua.

Đối với mỗi tin nhắn thiết bị mà máy chủ ứng dụng của bạn nhận được từ FCM, nó cần gửi một tin nhắn ACK. Nó không bao giờ cần gửi tin nhắn NACK. Nếu bạn không gửi ACK cho một tin nhắn, FCM sẽ gửi lại nó vào lần tiếp theo khi kết nối XMPP mới được thiết lập, trừ khi tin nhắn hết hạn trước.

FCM cũng gửi ACK hoặc NACK cho mỗi tin nhắn từ máy chủ đến thiết bị. Nếu bạn không nhận được, điều đó có nghĩa là kết nối TCP đã bị đóng giữa chừng và máy chủ của bạn cần gửi lại thư. Xem Kiểm soát luồng để biết chi tiết.

Xem Tham chiếu giao thức để biết danh sách tất cả các tham số thông báo.

định dạng yêu cầu

Tin nhắn có trọng tải — tin nhắn thông báo

Đây là một khổ thơ XMPP cho một tin nhắn thông báo:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
     "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
     "notification": {
        "title": "Portugal vs. Denmark”,
        "body”: "5 to 1”
      },
      "time_to_live":"600"
  }
  </gcm>
</message>

Tin nhắn có trọng tải — tin nhắn dữ liệu

Đây là một khổ thơ XMPP chứa thông báo JSON từ máy chủ ứng dụng đến FCM:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
      "message_id":"m-1366082849205" // new required field
      "data":
      {
          "hello":"world",
      }
      "time_to_live":"600",
  }
  </gcm>
</message>

định dạng phản hồi

Phản hồi FCM có thể có ba dạng có thể. Tin nhắn đầu tiên là tin nhắn 'ack' thông thường. Nhưng khi phản hồi có lỗi, thông báo có thể có 2 dạng khác nhau, được mô tả bên dưới.

tin nhắn ACK

Đây là đoạn XMPP chứa thông báo ACK/NACK từ FCM đến máy chủ ứng dụng:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "from":"REGID",
      "message_id":"m-1366082849205"
      "message_type":"ack"
  }
  </gcm>
</message>

tin nhắn NACK

Lỗi NACK là một thông báo XMPP thông thường trong đó thông báo trạng thái message_type là "nack". Một tin nhắn NACK chứa:

  • Mã lỗi NACK.
  • Mô tả lỗi NACK.

Dưới đây là một số ví dụ.

Đăng ký xấu:

<message>
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"SomeInvalidRegistrationToken",
    "error":"BAD_REGISTRATION",
    "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId"
  }
  </gcm>
</message>

JSON không hợp lệ:

<message>
 <gcm xmlns="google:mobile:data">
 {
   "message_type":"nack",
   "message_id":"msgId1",
   "from":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
   "error":"INVALID_JSON",
   "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc"
 }
 </gcm>
</message>

Tốc độ tin nhắn của thiết bị đã vượt quá:

<message id="...">
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"REGID",
    "error":"DEVICE_MESSAGE_RATE_EXCEEDED",
    "error_description":"Downstream message rate exceeded for this registration id"
  }
  </gcm>
</message>

Xem Tham chiếu máy chủ để biết danh sách đầy đủ các mã lỗi NACK. Trừ khi có chỉ định khác, không nên thử lại một thông báo NACKed. Các mã lỗi NACK không mong muốn sẽ được xử lý giống như INTERNAL_SERVER_ERROR .

lỗi khổ thơ

Bạn cũng có thể gặp lỗi khổ thơ trong một số trường hợp. Một lỗi khổ thơ chứa:

  • Mã lỗi khổ thơ.
  • Mô tả lỗi khổ thơ (văn tự do).

Ví dụ:

<message id="3" type="error" to="123456789@fcm.googleapis.com/ABC">
  <gcm xmlns="google:mobile:data">
     {"random": "text"}
  </gcm>
  <error code="400" type="modify">
    <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
      InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n
    </text>
  </error>
</message>

Thông báo kiểm soát

Theo định kỳ, FCM cần đóng kết nối để thực hiện cân bằng tải. Trước khi đóng kết nối, FCM sẽ gửi một thông báo CONNECTION_DRAINING để cho biết rằng kết nối đang bị rút cạn và sẽ sớm bị đóng. "Draining" đề cập đến việc tắt luồng tin nhắn đi vào kết nối, nhưng cho phép bất kỳ thứ gì đã có trong đường dẫn tiếp tục. Khi bạn nhận được thông báo CONNECTION_DRAINING , bạn nên ngay lập tức bắt đầu gửi thông báo đến một kết nối FCM khác, mở một kết nối mới nếu cần. Tuy nhiên, bạn nên giữ kết nối ban đầu mở và tiếp tục nhận các thông báo có thể đến qua kết nối (và ACK chúng)—FCM xử lý bắt đầu đóng kết nối khi nó sẵn sàng.

Thông báo CONNECTION_DRAINING trông như thế này:

<message>
  <data:gcm xmlns:data="google:mobile:data">
  {
    "message_type":"control"
    "control_type":"CONNECTION_DRAINING"
  }
  </data:gcm>
</message>

CONNECTION_DRAINING hiện là control_type duy nhất được hỗ trợ.

Kiểm soát lưu lượng

Mỗi tin nhắn được gửi tới FCM đều nhận được phản hồi ACK hoặc NACK. Thư chưa nhận được một trong những phản hồi này được coi là đang chờ xử lý. Nếu số lượng tin nhắn đang chờ xử lý đạt 100, máy chủ ứng dụng sẽ ngừng gửi tin nhắn mới và đợi FCM xác nhận một số tin nhắn đang chờ xử lý hiện có như minh họa trong hình 1:

Sơ đồ chi tiết luồng điều khiển giữa FCM và app server

Hình 1. Luồng tin nhắn/ack.

Ngược lại, để tránh làm quá tải máy chủ ứng dụng, FCM sẽ ngừng gửi nếu có quá nhiều thư chưa được xác nhận. Do đó, máy chủ ứng dụng phải "ACK" các tin nhắn ngược dòng, được nhận từ ứng dụng khách qua FCM, càng sớm càng tốt để duy trì luồng tin nhắn đến liên tục. Giới hạn tin nhắn đang chờ xử lý nói trên không áp dụng cho các ACK này. Ngay cả khi số lượng tin nhắn đang chờ xử lý đạt tới 100, máy chủ ứng dụng sẽ tiếp tục gửi ACK cho các tin nhắn nhận được từ FCM để tránh chặn gửi tin nhắn ngược dòng mới.

ACK chỉ hợp lệ trong ngữ cảnh của một kết nối. Nếu kết nối bị đóng trước khi một thông báo có thể được ACK, thì máy chủ ứng dụng sẽ đợi FCM gửi lại thông báo ngược dòng trước khi ACK lại. Tương tự, tất cả các tin nhắn đang chờ xử lý mà không nhận được ACK/NACK từ FCM trước khi đóng kết nối sẽ được gửi lại.