Jak wysłać powiadomienie Firebase do wszystkich urządzeń za pośrednictwem CURL?


85

Próbuję wysłać powiadomienie do wszystkich użytkowników aplikacji (na Androida), zasadniczo kopiując to, co się dzieje, gdy powiadomienie jest wysyłane za pośrednictwem konsoli administratora Firebase. Oto polecenie CURL, od którego zaczynam:

curl --insecure --header "Autoryzacja: key = AIzaSyBidmyauthkeyisfineL-6NcJxj-1JUvEM" --header "Content-Type: application / json" -d "{\" notification \ ": {\" title \ ": \" uwaga -Title \ ", \" body \ ": \" note-Body \ "}}" https://fcm.googleapis.com/fcm/send

Oto ten JSON przeanalizowany, aby był mniej męczący dla oczu:

{
"notification":{
    "title":"note-Title",
    "body":"note-Body"
    }
}

Odpowiedź, która wraca, to tylko dwa znaki:

do

To wszystko, słowo „do”. (Nagłówki zgłaszają 400) Podejrzewam, że ma to związek z brakiem „to” w moim JSON. Co w ogóle można by nazwać „do”? Nie mam zdefiniowanych tematów, a urządzenia się nie zarejestrowały. Mimo to nadal mogą otrzymywać powiadomienia z panelu administratora Firebase.

Chcę wypróbować pakiet JSON „tylko do danych” ze względu na niesamowite ograniczenie przetwarzania powiadomień Firebase, w którym jeśli Twoja aplikacja jest na pierwszym planie, powiadomienie jest przetwarzane przez TWOJĄ procedurę obsługi, ale jeśli Twoja aplikacja działa w tle, przetwarzane WEWNĘTRZNIE przez usługę Firebase i nigdy nie przekazywane do modułu obsługi powiadomień. NAJBLIŻSZE można to obejść, wysyłając żądanie powiadomienia przez API, ale TYLKO jeśli robisz to tylko z danymi. (Co z kolei uniemożliwia obsługę iOS i Androida tą samą wiadomością). Zastąpienie „powiadomienia” słowem „dane” w którymkolwiek z moich plików JSON nie przynosi żadnego efektu.

Ok, więc spróbowałem rozwiązania tutaj: Firebase Java Server wysyła powiadomienia push do wszystkich urządzeń, które wydają mi się mówić „Ok, mimo że powiadomienia dla wszystkich są możliwe przez konsolę administracyjną… nie jest to tak naprawdę możliwe przez API. " Obejście polega na tym, aby każdy klient zasubskrybował temat, a następnie wysłał powiadomienie do tego tematu. Więc najpierw kod w onCreate:

FirebaseMessaging.getInstance().subscribeToTopic("allDevices");

następnie nowy JSON, który wysyłam:

{
"notification":{
    "title":"note-Title",
    "body":"note-Body"
    },
"to":"allDevices"
}

Teraz przynajmniej otrzymuję prawdziwą odpowiedź z serwera. Odpowiedź JSON:

{
"multicast_id":463numbersnumbers42000,
"success":0,
"failure":1,
"canonical_ids":0,
"results":
    [
    {
    "error":"InvalidRegistration"
    }
    ]
}

Do tego dołączony jest kod HTTP 200. Ok ... zgodnie z https://firebase.google.com/docs/cloud-messaging/http-server-ref kod 200 z „InvalidRegistration” oznacza problem z tokenem rejestracyjnym . Może? Ponieważ ta część dokumentacji dotyczy serwera wiadomości. Czy serwer powiadomień jest taki sam? Niejasny. Widzę gdzie indziej, że temat może zająć kilka godzin, zanim stanie się aktywny. Wygląda na to, że byłoby to bezużyteczne do tworzenia nowych pokojów rozmów, więc to również wydaje się być wyłączone.

Byłem bardzo podekscytowany, gdy mogłem napisać od podstaw aplikację, która otrzymywała powiadomienia w ciągu zaledwie kilku godzin, podczas gdy nigdy wcześniej nie korzystałem z Firebase. Wygląda na to, że przed osiągnięciem poziomu, powiedzmy, dokumentacji Stripe.com długa droga.

Podsumowując: czy ktoś wie, jaki kod JSON ma dostarczyć, aby wysłać wiadomość do wszystkich urządzeń, na których działa aplikacja, aby odzwierciedlić funkcjonalność konsoli administracyjnej?


Sprawdź, czy używany przez Ciebie token API jest poprawny. Spróbuj także wysłać wiadomość GCM na jedno urządzenie i sprawdź, czy to działa. Możesz uzyskać InstanceId, uruchamiając aplikację w trybie debugowania i ustawiając punkt przerwania naFirebaseInstanceIdService
Justin Slade,

Podczas szybkiego wyszukiwania w Google na firebase.google.com/docs nie pojawia się „token API”. Masz na myśli „token identyfikacyjny”? lub „Token autoryzacji”? A może mówisz o moim kluczu autoryzacji podanym w nagłówku? Ten jest w porządku: jeśli zmienię go z tego, co jest, odpowiedź serwera zmieni się na „nieautoryzowane” zamiast na komunikat o błędzie, który obecnie otrzymuję.
Anders

Wygląda na to, że blog ten dotyczy wysyłania wiadomości na określone urządzenie, a nie jak w pierwotnej dyskusji, wysyłania jej tylko do wszystkich użytkowników aplikacji.
Anders 8

Przeczytaj ten post na blogu, aby uzyskać więcej informacji -> developine.com/…
Developine

Odpowiedzi:


55

EDYCJA: Wygląda na to, że ta metoda nie jest już obsługiwana (dzięki @FernandoZamperin). Proszę spojrzeć na inne odpowiedzi!

Zamiast subskrybować temat, możesz zamiast tego użyć conditionklucza i wysyłać wiadomości do instancji, które nie są w grupie. Twoje dane mogą wyglądać mniej więcej tak:

{
    "data": {
        "foo": "bar"
    },
    "condition": "!('anytopicyoudontwanttouse' in topics)"
}

Zobacz https://firebase.google.com/docs/cloud-messaging/send-message#send_messages_to_topics_2


3
to najlepsza odpowiedź. Można go uruchomić natychmiast, bez konieczności aktualizacji aplikacji. świetny!
Tom Marvolo Riddle

w końcu znalazłem ten - powinni naprawdę uczynić go bardziej oczywistym
cwiesner

Wygląda to obiecująco, ale czy naprawdę działa? Wygląda na włamanie. Wypróbowałem to na przykładowym projekcie i działa. Nie jestem jednak pewien, czy będzie działać z moją aplikacją do produkcji, która ma tysiące aktywnych użytkowników. Czy ktoś próbował tego z aplikacją do produkcji?
Sahil Patel

4
Stosowałem to podejście już od dłuższego czasu i działało idealnie, dziś z jakiegoś powodu wysyłam powiadomienie do starszego api zwraca mi komunikat message_id bez błędów, ale urządzenia nie otrzymują powiadomień push, żadne domysły co by to było problem? Przetestowano wysyłanie do pojedynczego tokena i działało normalnie.
Fernando Zamperin

1
@VitVeres Wysłałem problem do zespołu wsparcia Firebase, a oni odpowiedzieli mi: „Twoje obecne użycie wyrażeń w powiadomieniach push fanoutów nie jest obsługiwane. Upewnij się, że tematy wymienione w wyrażeniu istnieją dla Twojego projektu aplikacji.”, Więc ja chyba będę musiał zaimplementować tematy w moich aplikacjach.
Fernando Zamperin

98

Powiadomienia Firebase nie mają interfejsu API do wysyłania wiadomości. Na szczęście jest zbudowany na bazie Firebase Cloud Messaging, który ma właśnie takie API.

Dzięki powiadomieniom Firebase i usłudze Cloud Messaging możesz wysyłać tak zwane wiadomości przychodzące do urządzeń na trzy sposoby:

  1. do określonych urządzeń , jeśli znasz ich identyfikatory
  2. do grup urządzeń , jeśli znasz identyfikatory rejestracji grup
  3. do tematów , które są tylko kluczami, które urządzenia mogą subskrybować

Zauważysz, że nie ma możliwości bezpośredniego wysłania do wszystkich urządzeń. Możesz jednak zbudować taką funkcjonalność z każdym z nich, na przykład: subskrybując aplikację do tematu podczas jej uruchamiania (np. /topics/all) Lub przechowując listę wszystkich identyfikatorów urządzeń, a następnie wysyłając wiadomość do wszystkich.

Przy wysyłaniu do tematu w poleceniu występuje błąd składniowy. Tematy są identyfikowane zaczynając od /topics/. Ponieważ nie masz tego w swoim kodzie, serwer interpretuje allDevicesjako identyfikator urządzenia. Ponieważ jest to nieprawidłowy format tokenu rejestracji urządzenia, generuje błąd.

Z dokumentacji dotyczącej wysyłania wiadomości do tematów:

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to": "/topics/foo-bar",
  "data": {
    "message": "This is a Firebase Cloud Messaging Topic Message!",
   }
}

Próbowałem przesłać {"do": "/ topic / allDevices", "data": {"message": "To jest wiadomość na temat Firebase Cloud Messaging!"}} I otrzymałem tę samą odpowiedź InvalidRegistration. Przypuszczam, że to oznacza, że ​​temat jest nieprawidłowy. W konsoli nie widzę sposobu, aby spojrzeć na bazę tematów.
Anders

7
/topics/jest w liczbie mnogiej
Frank van Puffelen

uśmieszek Och, literówka, zmora programisty. ;) Nowa odpowiedź to: {"message_id": 5115052numbers95180}, która z pewnością wygląda na dużo bardziej skuteczną. Wydaje się więc, że najważniejsze jest to, że chociaż konsola administratora oferuje funkcję zasilania do dostarczania powiadomień za pośrednictwem „Powiadomień”, NIE ma sposobu, aby wyzwolić to z przesyłania przez API i należy po prostu przekonwertować się na używanie wiadomości. (Utrata planowania i śledzenia konwersji wbudowanych w Powiadomienia) Poszukam kodu wiadomości do obsługi odbioru. Dzięki Frank. :)
Anders8

1
Uhm ... nie do końca. Konsola powiadomień po prostu wysyła wiadomości z powiadomieniami (zobacz dokumentację dotyczącą typów wiadomości ). Jedyne, co robi, a nie mamy jeszcze interfejsu API, to wysyłanie do odbiorców .
Frank van Puffelen

1
czy to samo dotyczy iOS? Próbowałem tego samego i otrzymuję powiadomienie, gdy aplikacja jest
aktywna

73

Najłatwiejszy sposób, w jaki wymyśliłem wysyłanie powiadomienia push na wszystkie urządzenia, to zasubskrybowanie ich w temacie „wszystkie”, a następnie wysłanie powiadomienia na ten temat. Skopiuj to w swojej głównej aktywności

FirebaseMessaging.getInstance().subscribeToTopic("all");

Teraz wyślij żądanie jako

{
   "to":"/topics/all",
   "data":
   {
      "title":"Your title",
      "message":"Your message"
      "image-url":"your_image_url"
   }
}

Może to być nieefektywny lub niestandardowy sposób, ale jak wspomniałem powyżej jest najłatwiejszy. Napisz, jeśli masz lepszy sposób na wysłanie powiadomienia push do wszystkich urządzeń.

Możesz skorzystać z tego samouczka, jeśli nie masz doświadczenia w wysyłaniu powiadomień push za pomocą Firebase Cloud Messaging Samouczek - powiadomienia push przy użyciu FCM


Aby wysłać wiadomość do kombinacji tematów, określ warunek , który jest wyrażeniem logicznym określającym tematy docelowe. Na przykład następujący warunek spowoduje wysłanie wiadomości do urządzeń, które są subskrybowane TopicAi albo TopicBalbo TopicC:

{
   "data":
   {
      "title": "Your title",
      "message": "Your message"
      "image-url": "your_image_url"
   },
   "condition": "'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
}

Przeczytaj więcej o warunkach i tematach tutaj w dokumentacji FCM


To ma dla mnie sens. Ale tak jak ty, nie jestem pewien, czy jest to nieefektywne. Czy ktoś może to wyjaśnić?
JCarlosR

2
Nie sądzę, żeby to było nieefektywne, to może być jedyny możliwy sposób wysyłania powiadomień push na wszystkie urządzenia (nie mogłem znaleźć żadnego innego sposobu)
Syed Rafay

1
Najlepsza odpowiedź! :)
wonsuc

2
Świetna odpowiedź. Ponieważ nigdzie o tym nie wspomniano, ważne jest, aby wiedzieć, że otrzymasz tego rodzaju wiadomości w swoim Servicerozszerzeniu FirebaseMessagingServicew #onMessageReceivedfunkcji. Aby powiadomienie nie wyświetlało się automatycznie, musisz zająć się nim samodzielnie.
Odwróć

4

Jednym ze sposobów jest zasubskrybowanie tematu na wszystkich urządzeniach użytkowników. W ten sposób, gdy skierujesz wiadomość na określony temat, wszystkie urządzenia ją otrzymają. Myślę, że tak robi to sekcja Powiadomienia w konsoli Firebase.


Przeczytaj ten post na blogu, aby uzyskać więcej informacji -> developine.com/…
Developine

2

Szukałem rozwiązania dla powiadomień push w mojej aplikacji Ionic Cordova.

Dzięki odpowiedzi Syed Rafay.

w app.component.ts

const options: PushOptions = {
  android: {
    topics: ['all']
  },

w pliku serwera

"to" => "/topics/all",

1

Po prostu zmuś wszystkich użytkowników, którzy się logują, do subskrybowania określonego tematu, a następnie wyślij powiadomienie do tego tematu.


0

Sprawdź listę tematów w konsoli Firebase.

  1. Przejdź do konsoli Firebase

  2. Kliknij Rozwijaj z menu bocznego

  3. Kliknij opcję Komunikacja w chmurze

  4. Kliknij Wyślij pierwszą wiadomość

  5. W sekcji powiadomień wpisz tytuł powiadomienia i tekst powiadomienia

  6. Kliknij Dalej

  7. W sekcji docelowej kliknij Temat

  8. Kliknij pole tekstowe tematu wiadomości , a następnie możesz zobaczyć swoje tematy (nie utworzyłem tematu o nazwie android lub ios, ale widzę te dwa tematy.

  9. Podczas wysyłania powiadomienia push dodaj to jako swój stan.

    "stan" => "'wszystko' w tematach || 'android' w tematach || 'ios' w tematach",

Całe ciało

array(
    "notification"=>array(
        "title"=>"Test",
        "body"=>"Test Body",
    ),
    "condition"=> "'all' in topics || 'android' in topics || 'ios' in topics",
);

Jeśli masz więcej tematów, możesz dodać je z || (lub) warunek, wtedy wszyscy użytkownicy otrzymają Twoje powiadomienie. Przetestował i działał dla mnie.


-4

Możesz wysłać powiadomienie na wszystkie urządzenia za pomocą „/ topics / all”

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to": "/topics/all",
  "notification":{ "title":"Notification title", "body":"Notification body", "sound":"default", "click_action":"FCM_PLUGIN_ACTIVITY", "icon":"fcm_push_icon" },
  "data": {
    "message": "This is a Firebase Cloud Messaging Topic Message!",
   }
}

Czy to nowa funkcja? A może wymaga to subskrybowania przez aplikację „wszystkich”?
Anders 8

To domyślna funkcjonalność. Nie subskrybuję żadnego tematu. To działa na mnie. Ale zrobiłem rejestrację symboliczną. "getToken"
Siva Karuppiah

1
Otrzymałbyś identyfikator wiadomości, tak, ale nic nie jest wysyłane do żadnego urządzenia, chyba że masz temat o nazwie „wszystkie”.
Abdalrahman Shatou,

Nie. Otrzymałem powiadomienie na moich urządzeniach z Androidem (dwa). czy chcesz, żebym załączył mój zrzut ekranu? Tworzę moją aplikację na bazie ioinc.
Siva Karuppiah

To działa dla mnie. Nie wiem, dlaczego jest to odrzucane.
m1crdy
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.