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 serwera, w którym działa 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 poprawnie sformatowanych żądań wiadomości do zaplecza FCM.
  • Potrafi obsługiwać żądania i ponownie je wysyłać za pomocą 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 komunikatów, aby jednoznacznie identyfikować każdy wysyłany komunikat (backend FCM HTTP generuje identyfikatory komunikatów 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: używając pakietu Firebase Admin SDK lub surowych protokołów. Ze względu na obsługę popularnych języków programowania i wygodne metody obsługi uwierzytelniania i autoryzacji zalecaną metodą jest pakiet Firebase Admin SDK.

Opcje interakcji z serwerami FCM obejmują:
  • Firebase Admin SDK, który obsługuje Node , Java , Python , C# i Go .
  • Interfejs API FCM HTTP v1 , który jest najbardziej aktualną z opcji protokołu, z bezpieczniejszą autoryzacją i elastycznymi możliwościami przesyłania wiadomości na różnych platformach (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 HTTP v1, w większości przypadków zalecamy używanie tego interfejsu API.
  • Starszy protokół HTTP . W nowych projektach zdecydowanie zaleca się przyjęcie interfejsu API HTTP FCM v1 zamiast starszego protokołu.
  • Starszy protokół serwera XMPP . W nowych projektach zdecydowanie zaleca się przyjęcie interfejsu API HTTP FCM v1 zamiast starszego protokołu.

Pakiet SDK administratora Firebase dla FCM

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

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

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

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

Protokoły serwera FCM

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

Twój serwer aplikacji może używać tych protokołów oddzielnie lub razem. 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.

Komunikaty XMPP różnią się od komunikatów HTTP w następujący sposób:

  • Wiadomości upstream/downstream
    • HTTP: tylko pobieranie, chmura do urządzenia.
    • XMPP: Upstream i downstream (z urządzenia do chmury, z chmury do urządzenia).
  • 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 blokuje wysyłanie kolejnej wiadomości przez nadawcę do momentu otrzymania odpowiedzi.
    • XMPP: asynchroniczny. Serwery aplikacji wysyłają/odbierają wiadomości do/od wszystkich swoich urządzeń z pełną szybkością linii za pośrednictwem trwałych połączeń XMPP. Serwer połączeń XMPP wysyła asynchronicznie powiadomienia o potwierdzeniu lub niepowodzeniu (w postaci specjalnych komunikatów XMPP ACK i NACK zakodowanych w formacie JSON).
  • JSON
    • HTTP: wiadomości JSON wysyłane jako HTTP POST.
    • XMPP: komunikaty JSON zawarte w komunikatach XMPP.
  • Zwykły tekst
    • HTTP: zwykłe wiadomości tekstowe wysyłane jako HTTP POST.
    • XMPP: Nieobsługiwane.
  • Wysyłanie multiemisji do wielu tokenów rejestracji.
    • HTTP: obsługiwany 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 kluczy JSON. Aby uzyskać szczegółowe informacje na temat opcji nagłówka i treści, zobacz Build App Server Send Requests

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 pole message_id , które jest wymagane. Ten identyfikator jednoznacznie identyfikuje wiadomość w połączeniu XMPP. ACK lub NACK z FCM używa message_id do identyfikowania wiadomości wysył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 stał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, wskazane przez pole message_type w obiekcie JSON. Wartością może być „ack” lub „nack” lub „control” (patrz formaty poniżej). Każda wiadomość FCM z nieznanym message_type wiadomości może zostać zignorowana przez Twój serwer.

W przypadku każdego komunikatu na urządzeniu, który serwer aplikacji odbiera 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 ​​je ponownie przy następnym nawiązaniu nowego połączenia XMPP, chyba że wiadomość wygaśnie wcześniej.

FCM wysyła również ACK lub NACK dla każdej wiadomości serwer-urządzenie. Jeśli ich nie otrzymasz, oznacza to, że połączenie TCP zostało zamknięte w trakcie operacji i Twój serwer musi ponownie wysłać wiadomości. Szczegółowe informacje można znaleźć w sekcji Sterowanie przepływem .

Listę wszystkich parametrów wiadomości można znaleźć w podręczniku Protocol Reference .

Format żądania

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

Oto sekcja XMPP dotycząca 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 komunikat 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 z nich to zwykła wiadomość 'ack'. Ale jeśli odpowiedź zawiera błąd, istnieją 2 różne formy wiadomości, opisane poniżej.

Potwierdź wiadomość

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ła wiadomość XMPP, w której komunikatem o statusie message_type jest „nack”. Wiadomość NACK zawiera:

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

Poniżej 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 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>

Zobacz Server Reference , aby uzyskać pełną listę kodów błędów NACK. O ile nie wskazano inaczej, wiadomości NACK nie należy ponawiać. Nieoczekiwane kody błędów NACK powinny być traktowane tak samo jak INTERNAL_SERVER_ERROR .

Błąd zwrotki

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

  • Kod błędu sekcji.
  • Opis błędu strofy (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 zamknąć połączenie, aby wykonać 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. „Opróżnianie” odnosi się do odcinania przepływu wiadomości przychodzących do połączenia, ale zezwalania na kontynuację 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 nowe połączenie w razie potrzeby. Należy jednak pozostawić otwarte połączenie i nadal odbierać komunikaty, które mogą nadejść przez połączenie (i potwierdzać je) — FCM obsługuje inicjowanie połączenia, gdy jest gotowe.

Komunikat CONNECTION_DRAINING wygląda tak:

<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 jednej 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 komunikatów. W związku z tym serwer aplikacji powinien jak najszybciej "ACK" wysyłać wiadomości odebrane z aplikacji klienckiej za pośrednictwem FCM, aby utrzymać stały przepływ wiadomości przychodzących. Wyżej wymieniony limit oczekujących wiadomości nie dotyczy tych ACK. Nawet jeśli liczba oczekujących komunikatów osiągnie 100, serwer aplikacji powinien nadal wysyłać potwierdzenia ACK dla komunikatów odebranych 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 komunikatu, serwer aplikacji powinien poczekać, aż FCM ponownie wyśle ​​komunikat nadrzędny przed ponownym potwierdzeniem. Podobnie wszystkie oczekujące wiadomości, dla których ACK/NACK nie zostały odebrane z FCM przed zamknięciem połączenia, powinny zostać ponownie wysłane.