Check out what’s new from Firebase@ Google I/O 2021, and join our alpha program for early access to the new Remote Config personalization feature. Learn more

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.

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 dla zaufanego środowiska serwerowego

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

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 co najmniej jednego tematu.
  • 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 . Następnie po zainstalowaniu pakietu Firebase Admin SDK możesz zacząć pisać logikę tworzenia żądań wysyłania .

Protokoły serwera FCM

Obecnie FCM udostępnia te surowe protokoły serwera:

Twój serwer aplikacji może korzystać z 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.

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 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 może zostać zignorowana przez serwer.

W przypadku 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 ​​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. Zobacz Kontrola przepływu, aby uzyskać szczegółowe informacje.

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:

01e33770

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

Pełną listę kodów błędów NACK można znaleźć w podręczniku Server Reference . 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 (tekst dowolny).

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 wiadomości CONNECTION_DRAINING należy natychmiast rozpocząć wysyłanie wiadomości do innego połączenia FCM, otwierając nowe połączenie w razie potrzeby. Należy jednak pozostawić otwarte połączenie i nadal otrzymywać 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:

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 kontynuować wysyłanie 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.