Firebase onMessageRicevuto non chiamato quando l'app in background


233

Sto lavorando con Firebase e sto testando l'invio di notifiche alla mia app dal mio server mentre l'app è in background. La notifica viene inviata correttamente, viene persino visualizzata nel centro notifiche del dispositivo, ma quando viene visualizzata la notifica o anche se faccio clic su di essa, il metodo onMessageReceived all'interno del mio FCMessagingService non viene mai chiamato.

Quando l'ho provato mentre la mia app era in primo piano, veniva chiamato il metodo onMessageReceived e tutto funzionava bene. Il problema si verifica quando l'app è in esecuzione in background.

È questo comportamento previsto o esiste un modo per risolverlo?

Ecco il mio 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"));
        }
    }
}

Oltre al corpo json, dov'è il tuo codice onTokenRefresh ? Hai completato la configurazione di Android ?
Kato,

4
Cosa intendi con il corpo json della notifica? Inoltre, il mio codice onTokenRefresh è all'interno del mio servizio FirebaseInstanceID.
Cyogenos,

Puoi pubblicare il payload di esempio che stai inviando?
AL.


È inoltre possibile controllare questa discussione stackoverflow.com/questions/39046270/...
. Md Sajedul Karim

Risposte:


144

Funziona come previsto, i messaggi di notifica vengono recapitati al callback onMessageReceived solo quando l'app è in primo piano. Se la tua app è in background o chiusa, nel centro di notifica viene visualizzato un messaggio di notifica e tutti i dati di quel messaggio vengono passati all'intento che viene avviato a seguito del tocco dell'utente sulla notifica.

È possibile specificare una click_action per indicare l'intenzione che deve essere avviata quando la notifica viene toccata dall'utente. L'attività principale viene utilizzata se non viene specificata alcuna click_action.

Quando viene avviato l'intento è possibile utilizzare il

getIntent().getExtras();

per recuperare un set che includa tutti i dati inviati insieme al messaggio di notifica.

Per ulteriori informazioni sul messaggio di notifica, consultare la documentazione .


6
C'è un modo per impostare click_actionquando sto usando Firebase Notification Console?
Nii Laryea,

6
ok, ma cosa succede se l'app viene uccisa (nessun primo piano o sfondo)?
Michalu,

3
Ma come disabilitare la notifica di eliminazione dell'utente? Perché se l'utente lo scarta, significa che tutti i dati verranno ignorati ... Giusto?
Aleksey Timoshchenko,

4
Corretta! Pertanto, quando si inviano messaggi di notifica ad Android, i dati di accompagnamento dovrebbero essere dati che migliorano l'esperienza di notifica. Non dovrebbero essere dati critici dell'app, utilizzare messaggi di dati per i dati di cui l'applicazione ha bisogno anche se l'utente rifiuta la notifica.
Arthur Thompson,

3
Questo non è del tutto corretto. Se il messaggio contiene solo dati e non un payload di notifica, il messaggio verrà SEMPRE consegnato a onMessageReceive, se l'app è in primo piano o meno.
JacksOnF1re

125

Rimuoverenotification completamente il campo dalla richiesta del server. Invia solodata e gestiscilo onMessageReceived()altrimentionMessageReceived() non verrai attivato quando l'app è in background o uccisa.

Non dimenticare di includere il "priority": "high"campo nella richiesta di notifica. Secondo la documentazione: i messaggi di dati vengono inviati con una priorità normale, quindi non arriveranno all'istante; potrebbe anche essere il problema.

Ecco cosa sto inviando dal server

{
  "data":{
    "id": 1,
    "missedRequests": 5
    "addAnyDataHere": 123
  },
  "to": "fhiT7evmZk8:APA91bFJq7Tkly4BtLRXdYvqHno2vHCRkzpJT8QZy0TlIGs......",
  "priority": "high"
}

Quindi puoi ricevere i tuoi dati in onMessageReceived(RemoteMessage message)questo modo .... diciamo che devo ottenere un ID

Object obj = message.getData().get("id");
        if (obj != null) {
            int id = Integer.valueOf(obj.toString());
        }

9
Ho scoperto che se invio solo un messaggio di dati, l'app che viene cancellata dal task manager non sarà in grado di ricevere la notifica. È un comportamento previsto?
Prabhjot Singh,

2
Questa è stata la soluzione per me per ricevere messaggi in background!
Ray Hulha,

5
In Oreo quando l'app viene uccisa, onMessageReceived non viene chiamato. ho solo payload con solo dati. qualche aggiornamento hai?
Samir Mangroliya,

2
Funziona come un fascino!
ssk

3
Ti amo molto per questa risposta: p
Ahmad Arslan,

63

questo metodo handleIntent () è stato ammortizzato, quindi la gestione di una notifica può essere eseguita come di seguito:

  1. Stato in primo piano: il clic della notifica passerà all'attività dell'intento in sospeso che si sta fornendo durante la creazione di una notifica in modo pro- grammatico in quanto generalmente creata con il payload di dati della notifica.

  2. Background / Killed State - Qui, il sistema stesso crea una notifica basata sul payload della notifica e facendo clic su tale notifica si accederà all'attività di avvio dell'applicazione in cui è possibile recuperare facilmente i dati Intent in uno dei metodi del ciclo di vita.


Grazie!!! Ho perso un paio di giorni su questo problema e questo mi ha salvato.
Igor Janković,

davvero la soluzione perfetta!
EduXavier,

4
Sto gestendo la logica di visualizzazione delle notifiche in handleIntent (Intent intent), tuttavia quando l'app è in background, vengono visualizzate 2 notifiche, una che ho creato e l'altra per impostazione predefinita che contiene l'intero messaggio dalla notifica.
Joyson,

5
Fantastico, ma OnMessageReceivedin questo caso non vedo alcun uso !?
Alaa Abu Zarifa,

8
Sto avendo com.google.firebase: Firebase-messaging: 11.6.2 & handleIntent è finale now.Check stackoverflow.com/questions/47308155/...
Ronak Poriya

31

Ecco concetti più chiari sul messaggio Firebase. L'ho trovato dal loro team di supporto.

Firebase ha tre tipi di messaggi :

Messaggi di notifica : il messaggio di notifica funziona in background o in primo piano. Quando l'app è in background, i messaggi di notifica vengono recapitati nella barra delle applicazioni. Se l'app è in primo piano, i messaggi vengono gestiti onMessageReceived()o didReceiveRemoteNotificationrichiamate. Questi sono essenzialmente i cosiddetti messaggi display.

Messaggi di dati : sulla piattaforma Android, il messaggio di dati può funzionare in background e in primo piano. Il messaggio di dati verrà gestito da onMessageReceived (). Una nota specifica della piattaforma qui sarebbe: Su Android, il payload dei dati può essere recuperato nell'intento utilizzato per avviare l'attività. Per elaborare, se lo hai "click_action":"launch_Activity_1", puoi recuperare questo intento getIntent()solo da Activity_1.

Messaggi con payload di notifica e dati : quando sono in background, le app ricevono il payload di notifica nell'area di notifica e gestiscono il payload di dati solo quando l'utente tocca la notifica. In primo piano, l'app riceve un oggetto messaggio con entrambi i payload disponibili. In secondo luogo, il parametro click_action viene spesso utilizzato nel payload delle notifiche e non nel payload dei dati. Se utilizzato all'interno del payload di dati, questo parametro verrebbe trattato come coppia chiave-valore personalizzata e pertanto sarà necessario implementare la logica personalizzata affinché funzioni come previsto.

Inoltre, ti consiglio di usare il metodo onMessageReceived (vedi messaggio Dati) per estrarre il pacchetto di dati. Dalla tua logica, ho controllato l'oggetto bundle e non ho trovato il contenuto previsto dei dati. Ecco un riferimento a un caso simile che potrebbe fornire maggiore chiarezza.

Dal lato server, la notifica Firebase dovrebbe essere il seguente formato :

Il lato server deve inviare l' oggetto "notifica" . Mancanza di oggetto "notifica" nel mio TargetActivitynon ho ricevuto il messaggio utilizzando getIntent().

Il formato del messaggio corretto è indicato di seguito:

{
 "data": {
  "body": "here is body",
  "title": "Title"
 },
"notification": {
  "body": "here is body",
  "title": "Title",
  "click_action": "YOUR_ACTION"
 },
 "to": "ffEseX6vwcM:APA91bF8m7wOF MY FCM ID 07j1aPUb"
}

Ecco concetti più chiari sul messaggio Firebase. L'ho trovato dal loro team di supporto.

Per maggiori informazioni visita il mio questo thread e questo thread


3
vale la pena ricordare che i "messaggi di dati" non verranno ricevuti se il dispositivo è in modalità deep doze (introdotto in Android 7.0). stai attento con quelli!
Sameer J,

30

Ho avuto lo stesso problema. È più semplice utilizzare il "messaggio dati" anziché la "notifica". Il messaggio di dati carica sempre la classe onMessageReceived.

In quella classe puoi effettuare la tua notifica con il notificationbuilder.

Esempio:

 @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        sendNotification(remoteMessage.getData().get("title"),remoteMessage.getData().get("body"));
    }

    private void sendNotification(String messageTitle,String messageBody) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,0 /* request code */, intent,PendingIntent.FLAG_UPDATE_CURRENT);

        long[] pattern = {500,500,500,500,500};

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_stat_name)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setVibrate(pattern)
                .setLights(Color.BLUE,1,1)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }

7
Grazie .. Ho cambiato il mio codice server e utilizzo "dati" invece di "notifica" e ora funziona perfettamente,
Mahesh Kavathiya,

5
@Koot funziona solo se l'app è in primo piano, non se è in background. mi potete aiutare ad attivare questo evento in entrambi i casi ??
Anant Shah,

@AnantShah come appare il tuo POST sul server Firebase?
Koot,

3
In realtà ci sono tre possibili casi qui. 1) App in primo piano. 2) App in background. 3) App non in esecuzione. Come dici tu, un messaggio di "dati" verrà ricevuto nei primi due casi, ma non nel terzo caso, quando l'app non è in esecuzione. Per soddisfare tutti e tre i casi, è necessario impostare il campo "notifica" nel messaggio. (Anche una buona idea se si desidera supportare i client iOS e Android)
Steve Moseley,

1
Anche se l'app non è in esecuzione, riceverò un messaggio dal server sulla funzione ricevuta. Sono d'accordo con te che è meglio usare la "notifica" se vuoi supportare anche iOS.
Koot

21

Secondo la documentazione di Firebase Cloud Messaging: se l'attività è in primo piano, verrà chiamato onMessageReceived. Se l'attività è in background o chiusa, nel centro di notifica viene visualizzato un messaggio di notifica per l'attività di avvio delle app. Puoi chiamare la tua attività personalizzata al clic della notifica se l'app è in background chiamando l'API del servizio di riposo per la messaggistica Firebase come:

URL- https://fcm.googleapis.com/fcm/send

Tipo di metodo: POST

Header- Content-Type:application/json
Authorization:key=your api key

Corpo / Carico utile:

{ "notification": {
    "title": "Your Title",
    "text": "Your Text",
     "click_action": "OPEN_ACTIVITY_1" // should match to your intent filter
  },
    "data": {
    "keyname": "any value " //you can get this data as extras in your activity and this data is optional
    },
  "to" : "to_id(firebase refreshedToken)"
} 

E con questo nella tua app puoi aggiungere il codice qui sotto nella tua attività da chiamare:

<intent-filter>
                <action android:name="OPEN_ACTIVITY_1" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

Dove vorrei creare l'intento e farlo aprire un'attività specifica? So che registra l'intento OPEN_ACTIVITY_1 nel manifest, ma dove lo chiamo?
Cyogenos,


Dovremmo chiamare un'attività dai filtri intent? O avviarlo manualmente onMessageReceived?
CoolMind,

14

Metodo onMessageReceived (RemoteMessage remoteMessage) chiamato in base ai seguenti casi.

  • Risposta FCM Con notifica e blocco dati :
{
  
"to": "device token list",
  "notification": {
    "body": "Body of Your Notification",
    "title": "Title of Your Notification"
  },
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}
  1. App in primo piano:

onMessageReceived (RemoteMessage remoteMessage) chiamato, mostra LargeIcon e BigPicture nella barra di notifica. Siamo in grado di leggere il contenuto sia dalla notifica che dal blocco dati

  1. App in background:

onMessageReceived (RemoteMessage remoteMessage) non chiamato, la barra delle applicazioni riceverà il messaggio e leggerà il corpo e il titolo dal blocco di notifica e mostrerà il messaggio e il titolo predefiniti nella barra di notifica.

  • Risposta FCM Con solo blocco dati :

In questo caso, rimuovere i blocchi di notifica da json

{
  
"to": "device token list",
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}

Soluzione per chiamare onMessageReceived ()

  1. App in primo piano:

onMessageReceived (RemoteMessage remoteMessage) chiamato, mostra LargeIcon e BigPicture nella barra di notifica. Siamo in grado di leggere il contenuto sia dalla notifica che dal blocco dati

  1. App in background:

onMessageReceived (RemoteMessage remoteMessage) chiamato, la barra delle applicazioni non riceverà il messaggio perché la chiave di notifica non è nella risposta. Mostra LargeIcon e BigPicture nella barra delle notifiche

Codice

 private void sendNotification(Bitmap bitmap,  String title, String 
    message, PendingIntent resultPendingIntent) {

    NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();
    style.bigPicture(bitmap);

    Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

    NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
    String NOTIFICATION_CHANNEL_ID = mContext.getString(R.string.default_notification_channel_id);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "channel_name", NotificationManager.IMPORTANCE_HIGH);

        notificationManager.createNotificationChannel(notificationChannel);
    }
    Bitmap iconLarge = BitmapFactory.decodeResource(mContext.getResources(),
            R.drawable.mdmlogo);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(mContext, NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(R.drawable.mdmlogo)
            .setContentTitle(title)
            .setAutoCancel(true)
            .setSound(defaultSound)
            .setContentText(message)
            .setContentIntent(resultPendingIntent)
            .setStyle(style)
            .setLargeIcon(iconLarge)
            .setWhen(System.currentTimeMillis())
            .setPriority(Notification.PRIORITY_MAX)
            .setChannelId(NOTIFICATION_CHANNEL_ID);


    notificationManager.notify(1, notificationBuilder.build());


}

Link di riferimento:

https://firebase.google.com/docs/cloud-messaging/android/receive


La parte più importante per le persone che soffrono di problemi in background è rimuovere la proprietà di "notifica" da JSON inviata dal server. questo risolve il problema. Molte grazie.
Ramy M. Mousa,

13

Ho avuto lo stesso problema. Se l'app è in primo piano, attiva il mio servizio in background dove posso aggiornare il mio database in base al tipo di notifica. Tuttavia, l'app passa in secondo piano: il servizio di notifica predefinito si occuperà di mostrare la notifica all'utente.

Ecco la mia soluzione per identificare l'app in background e attivare il servizio in background,

public class FirebaseBackgroundService extends WakefulBroadcastReceiver {

  private static final String TAG = "FirebaseService";

  @Override
  public void onReceive(Context context, Intent intent) {
    Log.d(TAG, "I'm in!!!");

    if (intent.getExtras() != null) {
      for (String key : intent.getExtras().keySet()) {
        Object value = intent.getExtras().get(key);
        Log.e("FirebaseDataReceiver", "Key: " + key + " Value: " + value);
        if(key.equalsIgnoreCase("gcm.notification.body") && value != null) {
          Bundle bundle = new Bundle();
          Intent backgroundIntent = new Intent(context, BackgroundSyncJobService.class);
          bundle.putString("push_message", value + "");
          backgroundIntent.putExtras(bundle);
          context.startService(backgroundIntent);
        }
      }
    }
  }
}

Nel manifest.xml

<receiver android:exported="true" android:name=".FirebaseBackgroundService" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </receiver>

Ho provato questa soluzione nell'ultima versione di Android 8.0. Grazie


condividi per usare questa classe FirebaseBackgroundService ?? @Nagendra Badiganti

dove utilizzare questo codice classe pubblica FirebaseBackgroundService estende WakefulBroadcastReceiver @Nagendra Badiganti

creare una classe di servizio nel pacchetto e registrarsi in manifest.xml. Assicurati di disporre del filtro per le tue notifiche. Poiché il servizio si attiva per ogni notifica GCM.
Nagendra Badiganti,

firebase.google.com/docs/cloud-messaging/android/… Sto seguendo questo link, devo aggiungere questa classe per ricevere la notifica. solo l'invio di un messaggio dal primo messaggio di firebase .. dice completato ma non riceve notifica @Nagendra Badiganti

1
WakefulBroadcastReceiverè obsoleto dal livello API 26.1.0.
Minoru,

12

Se l'app è in modalità background o inattiva (uccisa) e fai clic su Notifica , dovresti controllare il payload in LaunchScreen (nel mio caso la schermata di avvio è MainActivity.java).

Quindi in MainActivity.java su onCreate controlla gli extra :

    if (getIntent().getExtras() != null) {
        for (String key : getIntent().getExtras().keySet()) {
            Object value = getIntent().getExtras().get(key);
            Log.d("MainActivity: ", "Key: " + key + " Value: " + value);
        }
    }

Come posso ottenere il titolo, il corpo e i dati delle notifiche?
Md.Tarikul Islam

1
Grazie, questa è la risposta. @ Md.Tarikul Islam usando onMessageReceived () come menzionato in questa domanda.
Felixwcf,

7

Ignora il handleIntentMetodo delle FirebaseMessageServiceopere per me.

qui il codice in C # (Xamarin)

public override void HandleIntent(Intent intent)
{
    try
    {
        if (intent.Extras != null)
        {
            var builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            foreach (string key in intent.Extras.KeySet())
            {
                builder.AddData(key, intent.Extras.Get(key).ToString());
            }

            this.OnMessageReceived(builder.Build());
        }
        else
        {
            base.HandleIntent(intent);
        }
    }
    catch (Exception)
    {
        base.HandleIntent(intent);
    }
}

e questo è il codice in Java

public void handleIntent(Intent intent)
{
    try
    {
        if (intent.getExtras() != null)
        {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            for (String key : intent.getExtras().keySet())
            {
                builder.addData(key, intent.getExtras().get(key).toString());
            }

            onMessageReceived(builder.build());
        }
        else
        {
            super.handleIntent(intent);
        }
    }
    catch (Exception e)
    {
        super.handleIntent(intent);
    }
}

handleIntent () è definitivo
Ettore il

@Ettore Come posso invocare la funzione handleIntent?
Hiroto,

Il metodo viene chiamato quando si riceve il messaggio da Firebase, ma non è possibile eseguire l'override perché il metodo è dichiarato finale. (Firebase 11.6.0)
Ettore,

5

Per impostazione predefinita, l' attività di avvio nella tua app verrà avviata quando l'app è in background e fai clic sulla notifica, se hai qualche parte di dati con la tua notifica puoi gestirla nella stessa attività come segue,

if(getIntent().getExtras()! = null){
  //do your stuff
}else{
  //do that you normally do
}

Se navigo da mainActivity, come tornerà a una determinata attività funzionerà?
Mac_Play

@Uzair getIntent (). GetExtras () sempre null, hai qualche altra soluzione? Quando l'app sta andando in bacground suMessageReceived il metodo non chiama
user2025187

3

Se l'app è in background Fire-base mediante notifica di gestione predefinita Ma se vogliamo una nostra notifica personalizzata, dobbiamo cambiare il nostro lato server, che è responsabile per l'invio dei nostri dati personalizzati (payload dei dati)

Rimuovere completamente il payload di notifica dalla richiesta del server. Invia solo dati e gestiscili in onMessageReceived (), altrimenti onMessageReceived non verrà attivato quando l'app è in background o uccisa.

ora, il formato del codice lato server è simile a,

{
  "collapse_key": "CHAT_MESSAGE_CONTACT",
  "data": {
    "loc_key": "CHAT_MESSAGE_CONTACT",
    "loc_args": ["John Doe", "Contact Exchange"],
    "text": "John Doe shared a contact in the group Contact Exchange",
    "custom": {
      "chat_id": 241233,
      "msg_id": 123
    },
    "badge": 1,
    "sound": "sound1.mp3",
    "mute": true
  }
}

NOTA : vedere questa riga nel codice
"testo" sopra : "John Doe ha condiviso un contatto nel gruppo Scambio di contatti" nel payload dei dati, è necessario utilizzare il parametro "testo" anziché i parametri "corpo" o "messaggio" per la descrizione del messaggio o qualsiasi altra cosa vuoi usare il testo.

onMessageReceived ()

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.e(TAG, "From: " + remoteMessage.getData().toString());

        if (remoteMessage == null)
            return;

        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
           /* Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());*/
            Log.e(TAG, "Data Payload: " + remoteMessage);

            try {

                Map<String, String> params = remoteMessage.getData();
                JSONObject json = new JSONObject(params);
                Log.e("JSON_OBJECT", json.toString());


                Log.e(TAG, "onMessageReceived: " + json.toString());

                handleDataMessage(json);
            } catch (Exception e) {
                Log.e(TAG, "Exception: " + e.getMessage());
            }
        }
    }

2

Basta chiamare questo nel metodo onCreate di MainActivity:

if (getIntent().getExtras() != null) {
           // Call your NotificationActivity here..
            Intent intent = new Intent(MainActivity.this, NotificationActivity.class);
            startActivity(intent);
        }

Se navigo da mainActivity, come tornerà a una determinata attività funzionerà?
Mac_Play

2

secondo la soluzione di t3h Exi vorrei pubblicare qui il codice pulito. Basta inserirlo in MyFirebaseMessagingService e tutto funziona bene se l'app è in modalità background. Devi almeno compilare com.google.firebase: firebase-messaging: 10.2.1

 @Override
public void handleIntent(Intent intent)
{
    try
    {
        if (intent.getExtras() != null)
        {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            for (String key : intent.getExtras().keySet())
            {
                builder.addData(key, intent.getExtras().get(key).toString());
            }



           onMessageReceived(builder.build());
        }
        else
        {
            super.handleIntent(intent);
        }
    }
    catch (Exception e)
    {
        super.handleIntent(intent);
    }
}

Sto cercando di implementare la tua soluzione, ma il metodo handleIntent () è definitivo nella mia versione dell'SDK (SDK 27), quindi non posso
ignorarlo

Sì, ma non è colpa mia o nessun motivo per dare -1 !!! Molto arrogante. Funziona fino a quando Firebase 11.4.2 quindi Google lo ha modificato (reso definitivo questo metodo). Quindi ora è necessario programmare la propria soluzione con notifica.
Frank,

Non ho dato un -1 ma un +1!
matdev,

Mi salvi il lavoro: P
amitabha2715,

2

Prova questo:

public void handleIntent(Intent intent) {
    try {
        if (intent.getExtras() != null) {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");
            for (String key : intent.getExtras().keySet()) {
            builder.addData(key, intent.getExtras().get(key).toString());
        }
            onMessageReceived(builder.build());
        } else {
            super.handleIntent(intent);
        }
    } catch (Exception e) {
        super.handleIntent(intent);
    }
}

handleIntent non è più utilizzato in firebase: 11.8.0 e versioni successive.
Shihab Uddin

1

Ho riscontrato questo problema (l'app non vuole aprirsi quando si fa clic su notifica se l'app è in background o chiusa) e il problema non è valido click_actionnel corpo della notifica, provare a rimuoverlo o modificarlo in qualcosa di valido.


1

Il punto che merita di essere messo in evidenza è che devi usare il messaggio dati - solo chiave dati - per far chiamare il gestore onMessageReceived anche quando l'app è in background. Non dovresti avere altre chiavi di messaggi di notifica nel tuo payload, altrimenti il ​​gestore non verrà attivato se l'app è in background.

È menzionato (ma non così enfatizzato nella documentazione FCM) qui:

https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

Usa il tuo app server e l'API del server FCM: imposta solo la chiave dati . Può essere pieghevole o non pieghevole.


1

Il backend con cui sto lavorando sta usando i messaggi di notifica e non i messaggi di dati. Quindi, dopo aver letto tutte le risposte, ho cercato di recuperare gli extra dal pacchetto dell'intento che viene all'attività avviata. Ma non importa da quali chiavi ho cercato di recuperaregetIntent().getExtras(); , il valore era sempre nullo.

Tuttavia, ho finalmente trovato il modo di inviare dati utilizzando i messaggi di notifica e recuperarli dall'intento.

La chiave qui è aggiungere il payload di dati al messaggio di notifica.

Esempio:

{
    "data": {
        "message": "message_body",
        "title": "message_title"
    },
    "notification": {
        "body": "test body",
        "title": "test title"
    },
    "to": "E4An.."
}

Dopo aver fatto ciò, sarai in grado di ottenere le tue informazioni in questo modo:

intent.getExtras().getString("title") sarà message_title

e intent.getExtras().getString("message") lo saràmessage_body

Riferimento


1

Se il tuo problema è legato alla visualizzazione di Big Image, ad esempio se stai inviando una notifica push con un'immagine dalla console di Firebase e visualizza l'immagine solo se l'app in primo piano. La soluzione a questo problema è inviare un messaggio push con solo campo dati. Qualcosa come questo:

{ "data": { "image": "https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg", "message": "Firebase Push Message Using API" "AnotherActivity": "True" }, "to" : "device id Or Device token" }

hai perso la virgola prima di "AnotherActivity". Il mio androide vibra ma in realtà non viene mostrato nulla (nessun testo, nessuna immagine, nessuna spinta).
jekaby il

1

Quando il messaggio viene ricevuto e l'app è in background, la notifica viene inviata agli intenti extra dell'attività principale.

È possibile verificare il valore aggiuntivo nella funzione oncreate () o onresume () dell'attività principale.

Puoi controllare i campi come dati, tabella ecc. (Quello specificato nella notifica)

per esempio ho inviato usando i dati come chiave

public void onResume(){
    super.onResume();
    if (getIntent().getStringExtra("data")!=null){
            fromnotification=true;
            Intent i = new Intent(MainActivity.this, Activity2.class);
            i.putExtra("notification","notification");
            startActivity(i);
        }

}

0

Stavo avendo lo stesso problema e ho approfondito ulteriormente questo aspetto. Quando l'app è in background, un messaggio di notifica viene inviato nell'area di notifica , MA viene inviato un messaggio di dati a onMessageReceived()
Vedere https://firebase.google.com/docs/cloud-messaging/downstream#monitor-token-generation_3
e https://github.com/firebase/quickstart-android/blob/master/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/MyFirebaseMessagingService.java

Per garantire che il messaggio che stai inviando, i documenti dicono: " Usa il tuo app server e l'API del server FCM: imposta solo la chiave dati. Può essere comprimibile o non comprimibile " .
Vedi https://firebase.google.com/ docs / cloud-messaging / concept-options # notifications_and_data_messages


0

Esistono due tipi di messaggi: messaggi di notifica e messaggi di dati. Se si invia solo un messaggio di dati, cioè senza oggetto di notifica nella stringa del messaggio. Sarebbe invocato quando l'app in background.


0

Controlla la risposta di @Mahesh Kavathiya. Per il mio caso, nel codice server ha solo questo:

{
"notification": {
  "body": "here is body",
  "title": "Title",
 },
 "to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

Devi cambiare in:

{
 "data": {
  "body": "here is body",
  "title": "Title",
  "click_action": "YOUR_ACTION"
 },
"notification": {
  "body": "here is body",
  "title": "Title"
 },
 "to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

Quindi, nel caso in cui l'app in Background, l'intento di attività predefinito extra ottenga "dati"

In bocca al lupo!


-1

Sostituisci il metodo OnCreate di FirebaseMessagingService. Viene chiamato quando l'app è in background:

public override void OnCreate()
{
    // your code
    base.OnCreate();
}

Questa risposta potrebbe essere più utile se si potesse aggiungere una spiegazione e collegarsi ad alcuni documenti. Puoi per favore dirci come questo dovrebbe aiutare?
Kilokahn,

@kilokahn Puoi spiegarmi cosa non capisci? il metodo indicato deve essere inserito nel codice che fa parte della domanda e risponde pienamente alla domanda. Il codice è per Xamarin, ma puoi semplicemente convertirlo in Java.
Renzo Ciot,

AFAIK La documentazione ufficiale ( firebase.google.com/docs/cloud-messaging/android/client ) non parla dell'override di OnCreate in un servizio che estende FirebaseMessagingService - se hai accesso alla documentazione che lo fa, forse puoi condividere un link? Inoltre, dalla tua risposta, non è chiaro come l'override di onCreate risolva il problema di onMessageReceived che non viene chiamato quando si fa clic sulla notifica, quindi la richiesta di ulteriori informazioni.
Kilokahn,

La documentazione non menziona l'override del metodo OnCreate, ma funziona perché lo sto usando in produzione. Il codice che si desidera inserire nel metodo onMessageReceived e che ovviamente serve per eseguire alcune operazioni in background può essere eseguito su OnCreate.
Renzo Ciot,

In tal caso, approfondire il fatto che in qualche modo ha funzionato per te può rivelarsi più utile del semplice elencare la soluzione. Inoltre, è probabile che il comportamento non documentato smetta arbitrariamente di funzionare con gli aggiornamenti e qualcuno che li utilizza deve essere pronto a rielaborare il proprio codice quando lo fa. Questo disclaimer deve essere inserito.
Kilokahn

-1

Esistono 2 tipi di notifiche push di Firebase :

1- Messaggio di notifica (Visualizza messaggio) -> - 1.1 Se si sceglie questa variante, il sistema operativo crea automaticamente una notifica se l'app è in background e passa i dati in intent. Quindi spetta al client gestire questi dati.

- 1.2 Se l'app è in primo piano, la notifica verrà ricevuta tramite callback-functionin FirebaseMessagingServicee spetta al client gestirla.

2- Messaggi di dati (fino a 4k di dati) -> Questi messaggi vengono utilizzati per inviare solo dati al client (in silenzio) e spetta al client gestirli per entrambi i casi in background / in primo piano tramite la funzione di callback in FirebaseMessagingService

Questo è secondo i documenti ufficiali: https://firebase.google.com/docs/cloud-messaging/concept-options

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.