了解 2023 年 Google I/O 大会上介绍的 Firebase 亮点。了解详情

Twoje środowisko serwerowe i FCM

Strona serwerowa Firebase Cloud Messaging składa się z dwóch komponentów:

  • Backend FCM dostarczony przez Google.
  • Twój serwer aplikacji lub inne zaufane środowisko serwerowe , w którym działa Twoja logika serwera, takie jak Cloud Functions dla Firebase lub inne środowiska chmurowe zarządzane przez Google.

Twój serwer aplikacji lub środowisko zaufanego serwera wysyła żądania wiadomości do zaplecza FCM, które następnie kieruje wiadomości do aplikacji klienckich działających na urządzeniach użytkowników.

Wymagania dotyczące środowiska zaufanego serwera

Twoje środowisko serwera aplikacji musi spełniać następujące kryteria:

  • Możliwość wysyłania odpowiednio sformatowanych żądań wiadomości do zaplecza FCM.
  • Możliwość obsługi żądań i ponownego wysyłania ich przy użyciu wykładniczego wycofywania.
  • Możliwość bezpiecznego przechowywania poświadczeń autoryzacji serwera i tokenów rejestracji klienta.
  • W przypadku protokołu XMPP (jeśli jest używany) serwer musi mieć możliwość generowania identyfikatorów wiadomości w celu jednoznacznej identyfikacji każdej wysyłanej wiadomości (zaplecze HTTP FCM generuje identyfikatory wiadomości i zwraca je w odpowiedzi). Identyfikatory wiadomości XMPP powinny być unikalne dla każdego identyfikatora nadawcy.

Wybór opcji serwera

Musisz wybrać sposób interakcji z serwerami FCM: przy użyciu pakietu SDK Firebase Admin lub protokołów RAW. Ze względu na obsługę popularnych języków programowania i wygodne metody obsługi uwierzytelniania i autoryzacji zalecaną metodą jest Firebase Admin SDK.

Opcje interakcji z serwerami FCM obejmują:

  • Pakiet Firebase Admin SDK obsługujący Node , Java , Python , C# i Go .
  • Interfejs API FCM HTTP v1 , który jest najnowszą opcją protokołu, z bezpieczniejszą autoryzacją i elastycznymi możliwościami przesyłania wiadomości między platformami (pakiet Firebase Admin SDK jest oparty na tym protokole i zapewnia wszystkie jego nieodłączne zalety). Ponieważ nowe funkcje są zazwyczaj dodawane tylko do interfejsu API protokołu HTTP w wersji 1, zalecamy korzystanie z tego interfejsu API w większości przypadków użycia.
  • Starszy protokół HTTP . Stanowczo zaleca się, aby nowe projekty przyjmowały interfejs API HTTP FCM v1 zamiast starszego protokołu.
  • Starszy protokół serwera XMPP . Stanowczo zaleca się, aby nowe projekty przyjmowały interfejs API HTTP FCM v1 zamiast starszego protokołu.

Firebase Admin SDK dla FCM

Interfejs API Admin FCM obsługuje uwierzytelnianie za pomocą zaplecza i ułatwia wysyłanie wiadomości oraz zarządzanie subskrypcjami tematów. Dzięki pakietowi Firebase Admin SDK możesz:

  • Wysyłaj wiadomości do poszczególnych urządzeń
  • Wysyłaj wiadomości do tematów i warunków, które pasują do jednego lub więcej tematów.
  • Subskrybuj i anuluj subskrypcję urządzeń do iz tematów
  • Konstruuj ładunki wiadomości dostosowane do różnych platform docelowych

Pakiet Admin Node.js SDK zapewnia metody wysyłania wiadomości do grup urządzeń.

Aby skonfigurować pakiet Firebase Admin SDK, zobacz Dodawanie pakietu Firebase Admin SDK do swojego serwera . Jeśli masz już projekt Firebase, zacznij od Dodaj pakiet SDK . Pamiętaj też o włączeniu Cloud Messagin API na stronie ustawień Cloud Messaging dla swojego projektu. Następnie, po zainstalowaniu Firebase Admin SDK, możesz zacząć pisać logikę do tworzenia żądań wysyłania .

Protokoły serwera FCM

Obecnie FCM udostępnia następujące surowe protokoły serwera:

Twój serwer aplikacji może używać tych protokołów osobno lub w tandemie. Ponieważ jest to najbardziej aktualne i najbardziej elastyczne rozwiązanie do wysyłania wiadomości na wiele platform, interfejs API FCM HTTP v1 jest zalecany wszędzie tam, gdzie jest to możliwe. Jeśli Twoje wymagania obejmują przesyłanie wiadomości z urządzeń do serwera, musisz zaimplementować protokół XMPP.

Przesyłanie wiadomości XMPP różni się od przesyłania wiadomości HTTP w następujący sposób:

  • Wiadomości nadrzędne/poniższe
    • HTTP: tylko w dół, z chmury do urządzenia.
    • XMPP: Upstream i downstream (z urządzenia do chmury, z chmury do urządzenia).
  • Przesyłanie wiadomości (synchroniczne lub asynchroniczne)
    • HTTP: synchroniczny. Serwery aplikacji wysyłają wiadomości jako żądania HTTP POST i czekają na odpowiedź. Mechanizm ten jest synchroniczny i uniemożliwia nadawcy wysłanie kolejnej wiadomości do czasu otrzymania odpowiedzi.
    • XMPP: asynchroniczny. Serwery aplikacji wysyłają/odbierają wiadomości do/ze wszystkich swoich urządzeń z pełną szybkością linii przez trwałe połączenia XMPP. Serwer połączeń XMPP wysyła powiadomienia o potwierdzeniu lub niepowodzeniu (w postaci specjalnych komunikatów XMPP ACK i NACK zakodowanych w formacie JSON) asynchronicznie.
  • JSON
    • HTTP: wiadomości JSON wysyłane jako HTTP POST.
    • XMPP: wiadomości JSON zamknięte w wiadomościach XMPP.
  • Zwykły tekst
    • HTTP: wiadomości zwykłego tekstu wysyłane jako HTTP POST.
    • XMPP: Nieobsługiwane.
  • Wysyłanie multiemisji w dół do wielu tokenów rejestracji.
    • HTTP: obsługiwane w formacie wiadomości JSON.
    • XMPP: Nieobsługiwane.

Implementacja protokołu serwera HTTP

Aby wysłać wiadomość, serwer aplikacji wysyła żądanie POST z nagłówkiem HTTP i treścią HTTP składającą się z par klucz-wartość JSON. Aby uzyskać szczegółowe informacje na temat opcji nagłówka i treści, zobacz Tworzenie żądań wysyłania serwera aplikacji

Implementacja protokołu serwera XMPP

Ładunek JSON dla komunikatów FCM jest podobny do protokołu HTTP, z następującymi wyjątkami:

  • Nie ma wsparcia dla wielu odbiorców.
  • FCM dodaje wymagane pole message_id . Ten identyfikator jednoznacznie identyfikuje wiadomość w połączeniu XMPP. ACK lub NACK z FCM używa message_id do identyfikacji wiadomości wysłanej z serwerów aplikacji do FCM. Dlatego ważne jest, aby ten message_id był nie tylko unikalny (na identyfikator nadawcy ), ale zawsze obecny.
  • XMPP używa klucza serwera do autoryzacji trwałego połączenia z FCM. Zobacz Autoryzuj żądania wysyłania, aby uzyskać więcej informacji.

Oprócz zwykłych komunikatów FCM wysyłane są komunikaty kontrolne, na co wskazuje pole message_type w obiekcie JSON. Wartością może być „ack”, „nack” lub „control” (zobacz formaty poniżej). Każda wiadomość FCM z nieznanym message_type może zostać zignorowana przez Twój serwer.

Dla każdego komunikatu urządzenia, który serwer aplikacji otrzymuje z FCM, musi wysłać komunikat ACK. Nigdy nie musi wysyłać wiadomości NACK. Jeśli nie wyślesz ACK dla wiadomości, FCM wyśle ​​ją ponownie przy następnym ustanowieniu nowego połączenia XMPP, chyba że wiadomość wygaśnie wcześniej.

FCM wysyła również potwierdzenie ACK lub NACK dla każdej wiadomości wysyłanej z serwera do urządzenia. Jeśli nie otrzymasz żadnego z nich, oznacza to, że połączenie TCP zostało zamknięte w trakcie operacji i Twój serwer musi ponownie wysłać wiadomości. Zobacz Sterowanie przepływem, aby uzyskać szczegółowe informacje.

Zobacz Protocol Reference , aby zapoznać się z listą wszystkich parametrów komunikatu.

Format żądania

Wiadomość z ładunkiem — powiadomienie

Oto sekcja XMPP dla wiadomości z powiadomieniem:

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

Wiadomość z ładunkiem — wiadomość z danymi

Oto sekcja XMPP zawierająca wiadomość JSON z serwera aplikacji do 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>

Format odpowiedzi

Odpowiedź FCM może mieć trzy możliwe formy. Pierwsza to zwykła wiadomość „ack”. Ale gdy odpowiedź zawiera błąd, wiadomość może przybrać dwie różne formy, opisane poniżej.

wiadomość ACK

Oto sekcja XMPP zawierająca komunikat ACK/NACK z FCM do serwera aplikacji:

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

Wiadomość NACK

Błąd NACK to zwykły komunikat XMPP, w którym komunikat o stanie message_type to „nack”. Wiadomość NACK zawiera:

  • Kod błędu NACK.
  • Opis błędu NACK.

Poniżej znajduje się kilka przykładów.

Zła rejestracja:

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

Nieprawidłowy kod JSON:

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

Przekroczono częstotliwość komunikatów urządzenia:

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

Pełną listę kodów błędów NACK można znaleźć w podręczniku Server Reference . O ile nie wskazano inaczej, komunikat NACKed nie powinien być ponawiany. Nieoczekiwane kody błędów NACK należy traktować tak samo jak INTERNAL_SERVER_ERROR .

Błąd strofy

W niektórych przypadkach możesz również uzyskać błąd zwrotki. Błąd zwrotki zawiera:

  • Kod błędu sekcji.
  • Opis błędu w sekcji (dowolny tekst).

Na przykład:

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

Komunikaty kontrolne

Okresowo FCM musi zamykać połączenie, aby przeprowadzić równoważenie obciążenia. Przed zamknięciem połączenia FCM wysyła komunikat CONNECTION_DRAINING , aby wskazać, że połączenie jest opróżniane i wkrótce zostanie zamknięte. „Drenaż” odnosi się do odcięcia przepływu komunikatów przychodzących do połączenia, ale umożliwienia kontynuacji tego, co już jest w potoku. Po otrzymaniu komunikatu CONNECTION_DRAINING należy natychmiast rozpocząć wysyłanie komunikatów do innego połączenia FCM, otwierając w razie potrzeby nowe połączenie. Powinieneś jednak zachować otwarte oryginalne połączenie i nadal odbierać wiadomości, które mogą nadejść przez połączenie (i potwierdzać je) — FCM obsługuje inicjowanie połączenia, zamykając je, gdy jest gotowe.

Komunikat CONNECTION_DRAINING wygląda następująco:

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

CONNECTION_DRAINING jest obecnie jedynym obsługiwanym control_type .

Kontrola przepływu

Każda wiadomość wysłana do FCM otrzymuje odpowiedź ACK lub NACK. Wiadomości, które nie otrzymały żadnej z tych odpowiedzi, są uważane za oczekujące. Jeśli liczba oczekujących wiadomości osiągnie 100, serwer aplikacji powinien przestać wysyłać nowe wiadomości i poczekać, aż FCM potwierdzi niektóre z istniejących oczekujących wiadomości, jak pokazano na rysunku 1:

Szczegółowy schemat przepływu sterowania między FCM a serwerem aplikacji

Rysunek 1. Przepływ wiadomości/potwierdzeń.

I odwrotnie, aby uniknąć przeciążenia serwera aplikacji, FCM przestaje wysyłać, jeśli jest zbyt wiele niepotwierdzonych wiadomości. W związku z tym serwer aplikacji powinien jak najszybciej "ACK" odbierać wiadomości wysyłane z aplikacji klienckiej za pośrednictwem FCM, aby utrzymać stały przepływ wiadomości przychodzących. Wspomniany limit oczekujących komunikatów nie dotyczy tych potwierdzeń. Nawet jeśli liczba oczekujących komunikatów osiągnie 100, serwer aplikacji powinien kontynuować wysyłanie potwierdzeń dla komunikatów otrzymanych z FCM, aby uniknąć blokowania dostarczania nowych komunikatów nadrzędnych.

Potwierdzenia ACK są ważne tylko w kontekście jednego połączenia. Jeśli połączenie zostanie zamknięte przed potwierdzeniem wiadomości, serwer aplikacji powinien poczekać, aż FCM ponownie wyśle ​​wiadomość nadrzędną, zanim ponownie ją potwierdzi. Podobnie wszystkie oczekujące komunikaty, dla których nie otrzymano potwierdzenia ACK/NACK z FCM przed zamknięciem połączenia, powinny zostać wysłane ponownie.