Pracuję z Firebase i testuję wysyłanie powiadomień do mojej aplikacji z mojego serwera, gdy aplikacja jest w tle. Powiadomienie jest wysyłane pomyślnie, pojawia się nawet w centrum powiadomień urządzenia, ale kiedy pojawia się powiadomienie lub nawet po kliknięciu, metoda onMessageReceived w mojej usłudze FCMessagingService nigdy nie jest wywoływana.
Kiedy przetestowałem to, gdy moja aplikacja była na pierwszym planie, wywołano metodę onMessageReceived i wszystko działało dobrze. Problem występuje, gdy aplikacja działa w tle.
Czy to jest zamierzone zachowanie, czy jest sposób, aby to naprawić?
Oto moja usługa FBMessagingService:
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class FBMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.i("PVL", "MESSAGE RECEIVED!!");
if (remoteMessage.getNotification().getBody() != null) {
Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getNotification().getBody());
} else {
Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getData().get("message"));
}
}
}
android
firebase
firebase-cloud-messaging
Cyogenos
źródło
źródło
Odpowiedzi:
Działa to zgodnie z przeznaczeniem, powiadomienia są dostarczane do wywołania zwrotnego onMessageReceived tylko wtedy, gdy aplikacja jest na pierwszym planie. Jeśli aplikacja znajduje się w tle lub jest zamknięta, w centrum powiadomień jest wyświetlana wiadomość z powiadomieniem, a wszelkie dane z tej wiadomości są przekazywane do celu, który jest uruchamiany w wyniku stuknięcia powiadomienia przez użytkownika.
Możesz określić kliknięcie, aby wskazać zamiar, który powinien zostać uruchomiony po stuknięciu powiadomienia przez użytkownika. Główna aktywność jest używana, jeśli nie określono aktywności kliknięcia.
Po uruchomieniu zamiaru możesz użyć
aby pobrać Zestaw, który zawierałby wszelkie dane wysłane wraz z powiadomieniem.
Więcej informacji na temat powiadomienia można znaleźć w dokumentacji .
źródło
click_action
kiedy korzystam z konsoli powiadomień Firebase?Usuń
notification
pole całkowicie z żądania serwera. Wysyłaj tylkodata
i obsługuj, wonMessageReceived()
przeciwnym razieonMessageReceived()
nie zostanie uruchomione, gdy aplikacja będzie działała w tle lub zostanie zabita.Nie zapomnij podać
"priority": "high"
pola we wniosku o powiadomienie. Zgodnie z dokumentacją: wiadomości danych są wysyłane z normalnym priorytetem, więc nie docierają natychmiast; może to być również problem.Oto, co wysyłam z serwera
Możesz więc otrzymać swoje dane w
onMessageReceived(RemoteMessage message)
ten sposób .... powiedzmy, że muszę dostać identyfikatorźródło
ta metoda handleIntent () została uznana za przestarzałą, więc obsługę powiadomienia można wykonać w następujący sposób:
Stan pierwszego planu: Kliknięcie powiadomienia spowoduje przejście do oczekującej aktywności Intent, którą podajesz podczas tworzenia powiadomienia pro gramatycznie, ponieważ generalnie jest ono tworzone z ładunkiem danych powiadomienia.
Tło / stan zabity - tutaj sam system tworzy powiadomienie na podstawie ładunku powiadomienia, a kliknięcie tego powiadomienia przeniesie Cię do działania uruchamiania aplikacji, w którym możesz łatwo pobrać dane zamiaru dowolną z metod cyklu życia.
źródło
OnMessageReceived
w tym przypadku!Oto bardziej jasne pojęcia na temat komunikatu bazy ogniowej. Znalazłem to od ich zespołu wsparcia.
Firebase ma trzy typy wiadomości :
Powiadomienia : Powiadomienie działa w tle lub na pierwszym planie. Gdy aplikacja działa w tle, powiadomienia są dostarczane na tacę systemową. Jeśli aplikacja jest na pierwszym planie, wiadomości są obsługiwane przez
onMessageReceived()
lubdidReceiveRemoteNotification
oddzwaniane. Są to tak zwane komunikaty displayowe.Wiadomości danych : na platformie Android wiadomości danych mogą działać w tle i na pierwszym planie. Komunikat danych będzie obsługiwany przez onMessageReceived (). Uwaga dotycząca konkretnej platformy brzmiałaby następująco: na Androidzie ładunek danych można odzyskać w celu, który posłużył do uruchomienia Twojej aktywności. Aby rozwinąć, jeśli tak
"click_action":"launch_Activity_1"
, możesz odzyskać ten zamiargetIntent()
tylko zActivity_1
.Wiadomości zawierające zarówno powiadomienia, jak i dane : w tle aplikacje odbierają ładunek powiadomień na pasku powiadomień i obsługują ładunek danych tylko wtedy, gdy użytkownik stuknie powiadomienie. Na pierwszym planie aplikacja otrzymuje obiekt wiadomości z dostępnymi obiema ładunkami. Po drugie, parametr klikalności jest często używany w treści powiadomienia, a nie w danych. Jeśli zostanie użyty wewnątrz ładunku danych, ten parametr będzie traktowany jako niestandardowa para klucz-wartość i dlatego konieczne będzie zaimplementowanie niestandardowej logiki, aby działał zgodnie z przeznaczeniem.
Ponadto zalecam użycie metody onMessageReceived (patrz Komunikat danych) w celu wyodrębnienia pakietu danych. Z twojej logiki sprawdziłem obiekt pakietu i nie znalazłem oczekiwanej zawartości danych. Oto odniesienie do podobnego przypadku, który może zapewnić większą przejrzystość.
Po stronie serwera powiadomienie firebase powinno mieć następujący format :
Strona serwera powinna wysłać obiekt „powiadomienia” . Brak obiektu „powiadomienia” w mojej
TargetActivity
wiadomości nie został użytygetIntent()
.Poprawny format wiadomości podano poniżej:
Oto bardziej jasne pojęcia na temat komunikatu bazy ogniowej. Znalazłem to od ich zespołu wsparcia.
Aby uzyskać więcej informacji odwiedź mój ten wątek i ten wątek
źródło
Miałem ten sam problem. Łatwiej jest używać „komunikatu danych” zamiast „powiadomienia”. Komunikat danych zawsze ładuje klasę onMessageReceived.
W tej klasie możesz dokonać własnego powiadomienia za pomocą narzędzia do tworzenia powiadomień.
Przykład:
źródło
Zgodnie z dokumentacją Firebase Cloud Messaging - jeśli Aktywność jest na pierwszym planie, onMessageReceived zostanie wywołany. Jeśli Aktywność znajduje się w tle lub jest zamknięta, w centrum powiadomień wyświetlana jest wiadomość z powiadomieniem o aktywności programu uruchamiającego aplikacje. Możesz zadzwonić do niestandardowej aktywności po kliknięciu powiadomienia, jeśli aplikacja działa w tle, dzwoniąc do interfejsu usługi spoczynkowej w celu wysłania wiadomości do bazy ogniowej jako:
URL- https://fcm.googleapis.com/fcm/send
Metoda typu - POST
Nadwozie / Ładowność:
Dzięki temu w swojej aplikacji możesz dodać poniższy kod w swojej działalności, aby się nazywać:
źródło
onMessageReceived
?Metoda onMessageReceived (RemoteMessage remoteMessage) wywoływana w oparciu o następujące przypadki.
Wywołano onMessageReceived (RemoteMessage remoteMessage) , pokazuje LargeIcon i BigPicture na pasku powiadomień. Możemy odczytać treść zarówno z powiadomienia, jak i bloku danych
Nie wywołano onMessageReceived (RemoteMessage remoteMessage) , taca systemowa otrzyma komunikat i odczyta treść i tytuł z bloku powiadomień oraz wyświetli domyślną wiadomość i tytuł na pasku powiadomień.
W takim przypadku usunięcie bloków powiadomień z json
Rozwiązanie do wywoływania onMessageReceived ()
Wywołano onMessageReceived (RemoteMessage remoteMessage) , pokazuje LargeIcon i BigPicture na pasku powiadomień. Możemy odczytać treść zarówno z powiadomienia, jak i bloku danych
Wywołano onMessageReceived (RemoteMessage remoteMessage) , taca systemowa nie otrzyma komunikatu, ponieważ klucz powiadomienia nie jest w odpowiedzi. Pokazuje LargeIcon i BigPicture na pasku powiadomień
Kod
Link referencyjny:
https://firebase.google.com/docs/cloud-messaging/android/receive
źródło
Mam ten sam problem. Jeśli aplikacja jest na pierwszym planie - uruchamia moją usługę w tle, w której mogę aktualizować bazę danych na podstawie typu powiadomienia. Ale aplikacja przechodzi w tło - domyślna usługa powiadomień zadba o to, aby pokazać powiadomienie użytkownikowi.
Oto moje rozwiązanie do identyfikacji aplikacji w tle i uruchomienia usługi w tle,
W pliku manifest.xml
Przetestowałem to rozwiązanie w najnowszej wersji Androida 8.0. Dzięki
źródło
WakefulBroadcastReceiver
jest przestarzałe od poziomu API 26.1.0.Jeśli aplikacja jest w trybie tła lub nieaktywne (zabity), i kliknij na powiadamianiu , należy sprawdzić, czy ładunek w LaunchScreen (w moim ekranie przypadek Launch MainActivity.java).
Więc w MainActivity.java na onCreate sprawdź Dodatki :
źródło
Zastąp dla mnie
handleIntent
MetodęFirebaseMessageService
prac.tutaj kod w C # (Xamarin)
i to jest Kod w Javie
źródło
Domyślnie aplikacja Aktywność uruchamiania w tobie zostanie uruchomiona, gdy aplikacja będzie działała w tle i klikniesz powiadomienie, jeśli masz część danych z powiadomieniem, możesz obsłużyć ją w tej samej czynności w następujący sposób,
źródło
Jeśli aplikacja jest domyślnie w tle powiadomienie Fire-base obsługuje powiadomienie. Ale jeśli chcemy niestandardowego powiadomienia, musimy zmienić stronę serwera, która jest odpowiedzialna za wysyłanie niestandardowych danych (ładunek danych)
Całkowicie usuń ładunek powiadomienia z żądania serwera. Wysyłaj tylko dane i obsługuj je w onMessageReceived (), w przeciwnym razie twoja onMessageReceived nie zostanie uruchomiona, gdy aplikacja będzie działała w tle lub zostanie zabita.
teraz format kodu po stronie serwera wygląda,
UWAGA : patrz ten wiersz w powyższym kodzie
„tekst”: „John Doe udostępnił kontakt w grupie Wymiana kontaktów” w ładunku danych należy użyć parametru „tekst” zamiast parametrów „treść” lub „wiadomość” do opisu wiadomości lub cokolwiek innego chcę użyć tekstu.
onMessageReceived ()
źródło
Po prostu wywołaj to w metodzie onCreate MainActivity:
źródło
zgodnie z rozwiązaniem z t3h Exi chciałbym opublikować tutaj czysty kod. Wystarczy umieścić go w MyFirebaseMessagingService i wszystko działa dobrze, jeśli aplikacja jest w trybie tła. Musisz przynajmniej skompilować com.google.firebase: firebase-messaging: 10.2.1
źródło
Spróbuj tego:
źródło
Miałem ten problem (aplikacja nie chce się otwierać po kliknięciu powiadomienia, jeśli aplikacja jest w tle lub jest zamknięta), a problem był nieprawidłowy
click_action
w ciele powiadomień, spróbuj usunąć lub zmienić go na coś ważnego.źródło
Punktem, który zasługuje na wyróżnienie, jest to, że musisz użyć komunikatu danych - tylko klucz danych - - aby uzyskać wywołanie onMessageReceived, nawet gdy aplikacja jest w tle. Twój ładunek nie powinien mieć żadnego innego klucza powiadomienia, w przeciwnym razie program obsługi nie zostanie uruchomiony, jeśli aplikacja będzie działać w tle.
Jest wspomniany (ale nie tak podkreślony w dokumentacji FCM) tutaj:
https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages
źródło
Backend, z którym pracuję, używa komunikatów powiadomień, a nie danych. Więc po przeczytaniu wszystkich odpowiedzi próbowałem odzyskać dodatki z pakietu zamiarów, które przychodzą do rozpoczętej działalności. Ale bez względu na to, które klucze próbowałem odzyskać
getIntent().getExtras();
, wartość była zawsze pusta.Jednak w końcu znalazłem sposób na wysyłanie danych za pomocą powiadomień i odzyskanie ich z zamiarem.
Kluczem tutaj jest dodanie ładunku danych do komunikatu powiadomienia.
Przykład:
Po wykonaniu tej czynności będziesz w stanie uzyskać informacje w ten sposób:
intent.getExtras().getString("title")
będziemessage_title
i
intent.getExtras().getString("message")
będziemessage_body
Odniesienie
źródło
Jeśli twój problem jest związany z wyświetlaniem dużego obrazu, tj. Jeśli wysyłasz powiadomienie wypychane z obrazem z konsoli firebase i wyświetla ono obraz tylko wtedy, gdy aplikacja jest na pierwszym planie. Rozwiązaniem tego problemu jest wysłanie wiadomości push z samym polem danych. Coś takiego:
źródło
Gdy wiadomość zostanie odebrana, a aplikacja jest w tle, powiadomienie zostanie wysłane do dodatkowej grupy docelowej głównej działalności.
Możesz sprawdzić dodatkową wartość w funkcji oncreate () lub onresume () głównej aktywności.
Możesz sprawdzić pola takie jak dane, tabela itp. (Te określone w powiadomieniu)
na przykład wysłałem używając danych jako klucza
źródło
Miałem ten sam problem i pogłębiłem tę sprawę. Gdy aplikacja jest w tle, powiadomienie jest wysyłane do zasobnika systemowego, ALE wiadomość z danymi jest wysyłana do
onMessageReceived()
Patrz https://firebase.google.com/docs/cloud-messaging/downstream#monitor-token-generation_3
i https://github.com/firebase/quickstart-android/blob/master/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/MyFirebaseMessagingService.java
Aby upewnić się, że wysyłana wiadomość, dokumenty mówią: „ Użyj serwera aplikacji i interfejsu API serwera FCM: Ustaw tylko klucz danych. Może być zwijany lub nieodwracalny ” .
Zobacz https://firebase.google.com/ docs / cloud-messaging / concept-options # notifications_and_data_messages
źródło
Istnieją dwa rodzaje wiadomości: powiadomienia i komunikaty danych. Jeśli wysyłasz tylko wiadomość danych, to znaczy, że w ciągu wiadomości nie ma obiektu powiadomienia. Zostanie wywołany, gdy aplikacja będzie działać w tle.
źródło
Sprawdź odpowiedź @Mahesh Kavathiya. W moim przypadku w kodzie serwera jest tylko tak:
Musisz zmienić na:
Następnie, w przypadku aplikacji w tle, domyślna zamiar działania dodatkowo otrzyma „dane”
Powodzenia!
źródło
Po prostu zastąp metodę OnCreate FirebaseMessagingService. Jest wywoływany, gdy aplikacja jest w tle:
źródło
Istnieją 2 rodzaje z Firebase push-powiadomień:
1- Komunikat powiadomienia (Wyświetl komunikat) -> - 1.1 Jeśli wybierzesz ten wariant, system operacyjny utworzy dla siebie powiadomienie, jeśli aplikacja jest w tle, i przekaże dane do
intent
. Następnie klient musi zająć się tymi danymi.- 1,2 Jeśli aplikacja jest w pierwszym planie następnie zgłoszeniu zostanie ona odebrana przez
callback-function
wFirebaseMessagingService
i to do klienta, aby go obsłużyć.2- Wiadomości z danymi (do 4k danych) -> Te wiadomości są używane do wysyłania tylko danych do klienta (po cichu) i do klienta należy obsługa danych w obu przypadkach w tle / na pierwszym planie za pomocą funkcji wywołania zwrotnego w
FirebaseMessagingService
Jest to zgodne z oficjalnymi dokumentami: https://firebase.google.com/docs/cloud-messaging/concept-options
źródło