Come gestire le notifiche quando l'app in background in Firebase


429

Ecco il mio manifest

    <service android:name=".fcm.PshycoFirebaseMessagingServices">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <service android:name=".fcm.PshycoFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

Quando l'app è in background e arriva la notifica, arriva la notifica predefinita e non esegue il mio codice di onMessageReceived.

Ecco il mio onMessageReceivedcodice Questo invoca se la mia app è in esecuzione in primo piano, non quando l'app è in background. Come eseguire questo codice anche quando l'app è in background?

// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // If the application is in the foreground handle both data and notification messages here.
    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
    data = remoteMessage.getData();
    String title = remoteMessage.getNotification().getTitle();
    String message = remoteMessage.getNotification().getBody();
    String imageUrl = (String) data.get("image");
    String action = (String) data.get("action");
    Log.i(TAG, "onMessageReceived: title : "+title);
    Log.i(TAG, "onMessageReceived: message : "+message);
    Log.i(TAG, "onMessageReceived: imageUrl : "+imageUrl);
    Log.i(TAG, "onMessageReceived: action : "+action);

    if (imageUrl == null) {
        sendNotification(title,message,action);
    } else {
        new BigPictureNotification(this,title,message,imageUrl,action);
    }
}
// [END receive_message]

1
È scritto nell'esempio di sostituzione di onMessageReceived () , dice la seconda riga di commento Not getting messages here? See why this may be: goo.gl/39bRNJ . La soluzione, come le risposte di seguito, è disponibile nella documentazione in Messaggi con payload sia di notifica che di dati
fllo

In breve, per riattivare l'app che hai ucciso, devi sempre inviare una notifica con oggetto dati per chiamare il gestore della classe del servizio di notifica FirebaseMessagingService.onMessageReceived () nella tua applicazione. Prova anche a inviarlo non dalla console di Firebase, ma per pubblicarlo da qualche altra parte (ad esempio il servizio di posta online di test).
Zon,

1
questa soluzione ha funzionato per me stackoverflow.com/a/44150822/6632278 la speranza aiuta. Buona fortuna
Tony Barajas,

cosa ".fcm." PshycoFirebaseMessagingServices è nel tuo manifest? Ricevo un errore di classe non trovato .. e non ho trovato da nessuna parte qual è questa prima parte del parametro.
Éder Rocha Bezerra,

Risposte:


661

1. Perché sta succedendo questo?

Esistono due tipi di messaggi in FCM (Firebase Cloud Messaging):

  1. Visualizza messaggi : questi messaggi attivano la onMessageReceived()richiamata solo quando l'app è in primo piano
  2. Messaggi dati : questi messaggi attivano la onMessageReceived()richiamata anche se l'app è in primo piano / in background / uccisa

NOTA: il team di Firebase non ha ancora sviluppato un'interfaccia utente da inviare data-messagesai tuoi dispositivi. Dovresti usare il tuo server per inviare questo tipo!



2. Come?

A tale scopo, è necessario eseguire una POSTrichiesta al seguente URL:

POST https://fcm.googleapis.com/fcm/send

intestazioni

  • Chiave: Content-Type , Valore: application/json
  • Chiave: Authorization , Valore: key=<your-server-key>

Corpo usando argomenti

{
    "to": "/topics/my_topic",
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     }
}

O se vuoi inviarlo a dispositivi specifici

{
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     },
    "registration_ids": ["{device-token}","{device2-token}","{device3-token}"]
}


NOTA: assicurarsi di non aggiungere la chiave JSON notification
NOTA: per ottenere la chiave del server, è possibile trovarla nella console di firebase:Your project -> settings -> Project settings -> Cloud messaging -> Server Key

3. Come gestire il messaggio di notifica push?

Ecco come gestisci il messaggio ricevuto:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String myCustomKey = data.get("my_custom_key");

     // Manage data
}

4
È possibile inviare le chiavi "dati" e "notifica" nella stessa notifica seguendo questi passaggi stackoverflow.com/a/42279260/2734021 :)
Daniel S.

15
Firebase team have not developed a UI to send data-messages to your devices, yet.Questo è cambiato nell'ultimo anno?
Hankrecords,

2
@Antonio In oreo quando l'app viene uccisa, onMessageReceived non viene chiamato. ho solo payload con solo dati. qualche aggiornamento hai?
Samir Mangroliya,

63
Quando l'app è in background onMessageReceivednon viene chiamata ed è un problema serio in FCM !!! Aggiorna anche la tua risposta.
Muhammad Babar

2
Bene, per me, sembra che questo accada su alcuni dispositivi Android. Ho passato ore a pensare che fosse un vero problema, ma poi si è rivelato essere nulla. Quindi il mio consiglio è di testarlo su diversi dispositivi. L'ho anche testato su una VM e ho ricevuto la notifica anche quando l'app è stata uccisa. Lo sto solo dicendo per risparmiare tempo a qualcuno.
Tarek-Dev

158

Per creare una libreria firebase per chiamare onMessageReceived () nei seguenti casi

  1. App in primo piano
  2. App in background
  3. L'app è stata uccisa

non devi inserire la "notifica" della chiave JSON nella tua richiesta all'API firebase, ma usa invece "dati", vedi sotto.

Il seguente messaggio non chiamerà onMessageReceived () quando l'app è in background o uccisa e non è possibile personalizzare la notifica.

{
   "to": "/topics/journal",
   "notification": {
   "title" : "title",
   "text": "data!",
   "icon": "ic_notification"
    }
}

ma invece usando questo funzionerà

{
  "to": "/topics/dev_journal",
   "data": {
       "text":"text",
       "title":"",
       "line1":"Journal",
       "line2":"刊物"
   }
} 

Fondamentalmente, il messaggio viene inviato nell'argomento RemoteMessage insieme all'oggetto dati come Mappa, quindi è possibile gestire la notifica in onMessageReceived come nello snippet qui

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();

     //you can get your text message here.
     String text= data.get("text");


     NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
        // optional, this is to make beautiful icon
             .setLargeIcon(BitmapFactory.decodeResource(
                                    getResources(), R.mipmap.ic_launcher))  
        .setSmallIcon(smallIcon)  //mandatory
      .......
    /*You can read more on notification here:
    https://developer.android.com/training/notify-user/build-notification.html
    https://www.youtube.com/watch?v=-iog_fmm6mE
    */
}

1
È possibile ottenere questo risultato dalla console di Firebase?
Koder,

@koder, sfortunatamente la console di Firebase non supporta questo, devi usare lo strumento per inviare richieste post-messaggio a firebase come curl o postman (plugin chrome), API di messaggistica firebase fai riferimento al documento qui - firebase.google.com/docs / cloud-messaging / http-server-ref
Teerakiat Chitawattanarat

1
questo è quello che stavo cercando da più di un giorno ..... Grazie mille ha funzionato perfettamente. e sarebbe meglio se spiegassi come la coppia di chiavi vale nei dati può essere gestita in onMessageReceived () per iniziare un'attività con quei valori.
Boopathi T,

25
Il tuo metodo funziona bene quando l'app è in background, tuttavia quando l'app viene uccisa non ricevo dati
Sanzhar,

8
Stesso problema di Sanzhar. Se l'app viene uccisa non ricevo alcun messaggio.
Giacomo M,

104

Ritengo che tutte le risposte siano incomplete ma tutte hanno qualcosa di cui hai bisogno per elaborare una notifica che contiene dati quando l'app è in background.

Segui questi passaggi e sarai in grado di elaborare le tue notifiche quando l'app è in background.

1. Aggiungi un filtro intento come questo:

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

a un'attività che si desidera elaborare i dati di notifica.

  1. Invia notifiche con il formato seguente:

    { 
     "notification" : {
            "click_action" : ".MainActivity", 
            "body" : "new Symulti update !", 
            "title" : "new Symulti update !", 
            "icon" : "ic_notif_symulti" }, 
     "data": { ... },
     "to" : "c9Vaa3ReGdk:APA91bH-AuXgg3lDN2WMcBrNhJZoFtYF9" }

La chiave qui è aggiungi

"click_action" : ".MainActivity"

dove .MainActivity è l'attività con il filtro intenti aggiunto nel passaggio 1.

  1. Ottieni informazioni "dati" dalla notifica in onCreate di ".MainActivity":

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //get notification data info
        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
           //bundle must contain all info sent in "data" field of the notification
        }
    }

E questo dovrebbe essere tutto ciò che devi fare. Spero che questo aiuti qualcuno :)


5
Questa dovrebbe essere la risposta corretta. Nessuno dei documenti dice nulla sulla richiesta di un click_action E di un Filtro intenti affinché la notifica venga visualizzata anche nella barra delle applicazioni. Sono entrambi richiesti.
airowe,

@airowe non sono tenuti a mostrare la notifica
AlwaysConfused

Ho blocchi di dati e notifiche ma non riesco a ricevere dati in attività?
Ashwani,

3
Non capisco come questa non sia la risposta accettata. Senza click_action, semplicemente non funzionerà. Mi ha salvato la giornata
Arun Shankar

4
Grazie per il tuo supporto @ArunShankar. La risposta accettata è stata risposta 7 mesi prima della mia ed è una buona risposta. Non riesco a capire perché nessuno parli di click_action ed è per questo che ho aggiunto la mia risposta. Sono molto felice che sia molto utile per molte persone ed è quello che conta alla fine della giornata :)
Daniel S.

42

Secondo la documentazione Firebase in invio a valle utilizzando Firebase , esiste un tipo di payload 2:

  1. dati

    Questo parametro consente di specificare le coppie chiave-valore personalizzate del payload del messaggio. L'app client è responsabile dell'elaborazione dei messaggi di dati. I messaggi di dati hanno solo coppie chiave-valore personalizzate.

  2. notifica

    Questo parametro consente di specificare le coppie chiave-valore predefinite e visibili dall'utente del payload di notifica. FCM visualizza automaticamente il messaggio ai dispositivi dell'utente finale per conto dell'app client. I messaggi di notifica hanno un set predefinito di chiavi visibili all'utente.

Quando sei in primo piano puoi ottenere i dati all'interno di FCM usando onMessageReceived () , puoi ottenere i tuoi dati dal payload dei dati .

data = remoteMessage.getData();
String customData = (String) data.get("customData");

Quando sei in background, FCM mostrerà la notifica nella barra delle applicazioni in base alle informazioni dal payload della notifica . Titolo, messaggio e icona utilizzati per la notifica sulla barra delle applicazioni vengono ricavati dal payload della notifica .

{
  "notification": {
        "title" : "title",
        "body"  : "body text",
        "icon"  : "ic_notification",
        "click_action" : "OPEN_ACTIVITY_1"
       }
}

Questo payload di notifica viene utilizzato quando si desidera mostrare automaticamente la notifica sulla barra delle applicazioni quando l'app è in background. Per ottenere i dati di notifica quando l'app in background, è necessario aggiungere click_action nel payload della notifica .

Se vuoi aprire la tua app ed eseguire un'azione specifica [mentre in background], imposta click_action nel payload delle notifiche e mappalo su un filtro di intenti nell'attività che desideri avviare. Ad esempio, imposta click_action su OPEN_ACTIVITY_1 per attivare un filtro intento come il seguente:

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

Metti quel filtro-intento sul tuo manifest, all'interno di uno dei tuoi tag attività. Quando fai clic sulla notifica, si aprirà l'app e passerà direttamente all'attività definita in click_action, in questo caso "OPEN_ACTIVTY_1". E all'interno di quell'attività puoi ottenere i dati:

Bundle b = getIntent().getExtras();
String someData = b.getString("someData");

Sto usando FCM per la mia app Android e utilizzo entrambi i payload. Ecco l'esempio JSON che sto usando:

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification",
    "click_action" : "OPEN_ACTIVITY_1"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}

"Metti quel filtro intento sul tuo manifest, all'interno del tag dell'applicazione." non puoi inserire intent-filter all'interno del tag dell'applicazione.
Kyrylo Zapylaiev,

i tuoi JSON non mostrano dove va il tasto click_action.
Josh,

questa non è la risposta giusta? cos'è l'azione clic n dove va? qualcuno dovrebbe votare o pulire questo
rana

1
@KyryloZapylaiev Ho appena corretto e aggiornato la risposta: "Metti quel filtro di intenti sul tuo manifest, all'interno di uno dei tuoi tag attività".
Dika,

1
@Josh aggiornato e formattato. puoi ricontrollarlo
Dika,

32

Secondo i documenti

Gestisci i messaggi in un'app in background

Quando l'app è in background, Android indirizza i messaggi di notifica sulla barra delle applicazioni. Un tocco dell'utente sulla notifica apre l'app di avvio per impostazione predefinita.

Ciò include i messaggi che contengono sia payload di notifica che dati. In questi casi, la notifica viene recapitata nella barra delle applicazioni del dispositivo e il payload dei dati viene consegnato negli extra dell'intento dell'attività di avvio.

Se desideri aprire la tua app ed eseguire un'azione specifica, imposta click_action nel payload delle notifiche e mappalo su un filtro di intenti nell'attività che desideri avviare. Ad esempio, imposta click_action su OPEN_ACTIVITY_1 per attivare un filtro intento come il seguente:

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

Modificare :

Basato su questa discussione :

Non è possibile impostare il payload click_action utilizzando Firebase Console. Potresti provare con un comando curl o un server http personalizzato

curl --header "Authorization: key=<YOUR_KEY_GOES_HERE>" 
     --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send  
     -d "{\"to\":\"/topics/news\",\"notification\": 
         {\"title\": \"Click Action Message\",\"text\": \"Sample message\",
            \"click_action\":\"OPEN_ACTIVITY_1\"}}"

1
hai ragione. ho letto i documenti. ma sono confuso dove metterlo nel mio manifest? devo eseguire il codice su onMessageReceived su quel file java in modo che cosa dovrei fare signore?
Parth Patel,

Non puoi fare in modo che l'app si chiami automaticamente su Messaggio ripristinato quando è in background. Invece è necessario gestire l'intento ricevuto e far chiamare il gestore. O probabilmente è meglio implementare una classe / un metodo separati chiamati sia da onMessageReveiced che dalla gestione delle intenzioni. Ho aggiunto il gestore a onNewIntent dell'attività principale e funziona bene per me.
diidu,

troppo tardi per rispondere alle domande di @Parath Patel, ma forse questo aiuterà qualcun altro con gli stessi problemi, dai un'occhiata alla mia risposta qui stackoverflow.com/a/42279260/2734021
Daniel S.

dove ha dovuto mettere questa azione per? per la mia attività o il servizio Firebasemessage?
Mahdi,

** il reindirizzamento a più notifiche non funziona? ad esempio: se ho tre notifiche da fcm sullo sfondo usando prima la notifica "click_action" reindirizzata correttamente e poi 2 notifiche clic il reindirizzamento dell'attività non funziona
prasanthMurugan

24

Funziona da luglio 2019

Android compilazioneSkkVersion 28, buildToolsVersion 28.0.3 e firebase-messaging: 19.0.1

Dopo molte ore di ricerche su tutte le altre domande e risposte StackOverflow e tentando innumerevoli soluzioni obsolete, questa soluzione è riuscita a mostrare le notifiche in questi 3 scenari:

- L'app è in primo piano:
la notifica viene ricevuta dal metodo onMessageReceived nella mia classe MyFirebaseMessagingService

- L'app è stata uccisa (non è in esecuzione in background): la notifica viene inviata automaticamente alla barra delle notifiche da FCM. Quando l'utente tocca la notifica, l'app viene avviata chiamando l'attività con android.intent.category.LAUNCHER nel manifest. È possibile ottenere la parte dei dati della notifica utilizzando getIntent (). GetExtras () con il metodo onCreate ().

- L'app è in background: la notifica viene inviata automaticamente alla barra delle notifiche da FCM. Quando l'utente tocca la notifica, l'app viene portata in primo piano avviando l'attività con android.intent.category.LAUNCHER nel manifest. Poiché la mia app ha launchMode = "singleTop" in quell'attività, il metodo onCreate () non viene chiamato perché è già stata creata un'attività della stessa classe, invece viene chiamato il metodo onNewIntent () di quella classe e ottieni i dati parte di la notifica lì utilizzando intent.getExtras ().

Passaggi: 1- Se definisci l'attività principale della tua app in questo modo:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:screenOrientation="portrait"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name=".MainActivity" />
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

2- aggiungi queste righe con il metodo onCreate () di MainActivity.class

Intent i = getIntent();
Bundle extras = i.getExtras();
if (extras != null) {
    for (String key : extras.keySet()) {
        Object value = extras.get(key);
        Log.d(Application.APPTAG, "Extras received at onCreate:  Key: " + key + " Value: " + value);
    }
    String title = extras.getString("title");
    String message = extras.getString("body");
    if (message!=null && message.length()>0) {
        getIntent().removeExtra("body");
        showNotificationInADialog(title, message);
    }
}

e questi metodi nello stesso MainActivity.class:

@Override
public void onNewIntent(Intent intent){
    //called when a new intent for this class is created.
    // The main case is when the app was in background, a notification arrives to the tray, and the user touches the notification

    super.onNewIntent(intent);

    Log.d(Application.APPTAG, "onNewIntent - starting");
    Bundle extras = intent.getExtras();
    if (extras != null) {
        for (String key : extras.keySet()) {
            Object value = extras.get(key);
            Log.d(Application.APPTAG, "Extras received at onNewIntent:  Key: " + key + " Value: " + value);
        }
        String title = extras.getString("title");
        String message = extras.getString("body");
        if (message!=null && message.length()>0) {
            getIntent().removeExtra("body");
            showNotificationInADialog(title, message);
        }
    }
}


private void showNotificationInADialog(String title, String message) {

    // show a dialog with the provided title and message
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.cancel();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();
}

3- creare la classe MyFirebase in questo modo:

package com.yourcompany.app;

import android.content.Intent;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {


    public MyFirebaseMessagingService() {
        super();
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        Log.d(Application.APPTAG, "myFirebaseMessagingService - onMessageReceived - message: " + remoteMessage);

        Intent dialogIntent = new Intent(this, NotificationActivity.class);
        dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        dialogIntent.putExtra("msg", remoteMessage);
        startActivity(dialogIntent);

    }

}

4- creare una nuova classe NotificationActivity.class in questo modo:

package com.yourcompany.app;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ContextThemeWrapper;

import com.google.firebase.messaging.RemoteMessage;

public class NotificationActivity extends AppCompatActivity {

private Activity context;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = this;
    Bundle extras = getIntent().getExtras();

    Log.d(Application.APPTAG, "NotificationActivity - onCreate - extras: " + extras);

    if (extras == null) {
        context.finish();
        return;
    }

    RemoteMessage msg = (RemoteMessage) extras.get("msg");

    if (msg == null) {
        context.finish();
        return;
    }

    RemoteMessage.Notification notification = msg.getNotification();

    if (notification == null) {
        context.finish();
        return;
    }

    String dialogMessage;
    try {
        dialogMessage = notification.getBody();
    } catch (Exception e){
        context.finish();
        return;
    }
    String dialogTitle = notification.getTitle();
    if (dialogTitle == null || dialogTitle.length() == 0) {
        dialogTitle = "";
    }

    AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(context, R.style.myDialog));
    builder.setTitle(dialogTitle);
    builder.setMessage(dialogMessage);
    builder.setPositiveButton(getResources().getString(R.string.accept), new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.cancel();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();

}

}

5- Aggiungi queste righe al Manifest dell'app, all'interno dei tag

    <service
        android:name=".MyFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id"/>

    <activity android:name=".NotificationActivity"
        android:theme="@style/myDialog"> </activity>

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/notification_icon"/>

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/color_accent" />

6- aggiungere queste righe nel metodo Application.java onCreate () o nel metodo MainActivity.class onCreate ():

      // notifications channel creation
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      // Create channel to show notifications.
      String channelId = getResources().getString("default_channel_id");
      String channelName = getResources().getString("General announcements");
      NotificationManager notificationManager = getSystemService(NotificationManager.class);
      notificationManager.createNotificationChannel(new NotificationChannel(channelId,
              channelName, NotificationManager.IMPORTANCE_LOW));
  }

Fatto.

Ora affinché funzioni correttamente nei 3 scenari citati, è necessario inviare la notifica dalla console Web di Firebase nel modo seguente:

Nella sezione Notifica: Titolo notifica = Titolo da visualizzare nella finestra di notifica (opzionale) Testo notifica = Messaggio da mostrare all'utente (richiesto) Quindi nella sezione Destinazione: App = la tua app Android e nella sezione Opzioni aggiuntive: Canale di notifica Android = default_channel_id Chiave dati personalizzati: valore titolo: (stesso testo qui nel campo Titolo della sezione Notifica) chiave: valore corporeo: (stesso testo qui nel campo Messaggio della sezione Notifica) chiave: valore click_action: .MainActivity Sound = Disabilitato
scade = 4 settimane

Puoi eseguire il debug nell'emulatore con API 28 con Google Play.

Buona programmazione!


2
Grazie per questa grande risposta.
Alex Chengalan,

@alvaro, Se voglio aprire Url quando ricevo una notifica, come posso
gestirla

non funziona sul telefono opp in vivo quando l'app è chiusa o uccisa
Sviluppatore Android

Non ho provato su un telefono Vivo ma attualmente funziona su molti altri telefoni Android. Leggere lentamente ogni passaggio, controllare tutti i dettagli, quindi attivare il debug dei punti di interruzione nella prima riga di ciascuno dei metodi che ho menzionato qui, collegare un telefono reale al computer di sviluppo con un cavo e eseguire il debug dell'app durante l'invio un messaggio di FCM. Verifica di inviare i messaggi FCM con tutti i parametri e il formato che ho citato. In bocca al lupo!
alvaro,

2
Questa è la risposta più aggiornata, come ora dice la documentazione di Firebase: quando l'app è in background, Android indirizza i messaggi di notifica nella barra delle applicazioni. Un tocco dell'utente sulla notifica apre l'app di avvio per impostazione predefinita. Ciò include i messaggi che contengono sia payload di notifica che dati. In questi casi, la notifica viene recapitata nella barra delle applicazioni del dispositivo e il payload dei dati viene consegnato negli extra dell'intento dell'attività di avvio. ( firebase.google.com/docs/cloud-messaging/android/… ) Tante vecchie risposte non sono aggiornate
Riot Goof Woof

20

Poiché i messaggi display-messagesinviati dall'interfaccia utente di notifica Firebase funzionano solo se l'app è in primo piano. Per data-messages, è necessario effettuare una chiamata POST a FCM

passi

  1. Installa l'estensione Google Chrome di Advanced Rest Client inserisci qui la descrizione dell'immagine

  2. Aggiungi le seguenti intestazioni

    Chiave : Content-Type, Valore : application / json

    Chiave : autorizzazione, Valore : chiave = "chiave del server" inserisci qui la descrizione dell'immagine

  3. Aggiungi il corpo

    • Se si utilizzano argomenti:

      {
          "to" : "/topics/topic_name",
          "data": {
          "key1" : "value1",
          "key2" : "value2",
          }
      }
    • Se si utilizza l'ID di registrazione:

      {
          "registration_ids" : "[{"id"},{id1}]",
          "data": {
          "key1" : "value1",
          "key2" : "value2",
           }
      }

Questo è tutto!. Ora ascolta il onMessageReceivedcallback come al solito.

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String value1 = data.get("key1");
     String value2 = data.get("key2");
}

20

Per acquisire il messaggio in background è necessario utilizzare a BroadcastReceiver

import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.legacy.content.WakefulBroadcastReceiver
import com.google.firebase.messaging.RemoteMessage

class FirebaseBroadcastReceiver : WakefulBroadcastReceiver() {

    val TAG: String = FirebaseBroadcastReceiver::class.java.simpleName

    override fun onReceive(context: Context, intent: Intent) {

        val dataBundle = intent.extras
        if (dataBundle != null)
            for (key in dataBundle.keySet()) {
                Log.d(TAG, "dataBundle: " + key + " : " + dataBundle.get(key))
            }
        val remoteMessage = RemoteMessage(dataBundle)
        }
    }

e aggiungilo al tuo manifest:

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

7
Questo riceve davvero il messaggio di notifica, quando l'app è in background. Ma non impedisce al ricevitore Firebase predefinito di gestirlo, quindi il messaggio viene comunque visualizzato come avviso di notifica.
Galya,

Al momento non funziona, quindi è per questo che sto proponendo questa soluzione. C'è un bug archiviato nella base di bug di Google. Potresti voler dare un'occhiata.
Romulano,

Potresti per favore pubblicare un link al bug qui
Galya,

come ottenere i dati dalla notifica?
Ravi Vaghela

Questo chiaramente non funziona quando l'app viene uccisa. Ho provato questa soluzione per ore. per qualche motivo il ricevitore funziona mentre l'app è in background e non funziona quando l'app viene uccisa
XcodeNOOB

16
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

}

non viene chiamato ogni volta che viene chiamato solo quando l'app è in primo piano

esiste un metodo di sostituzione, questo metodo viene chiamato ogni volta, indipendentemente dall'app in primo piano o in background o uccisa, ma questo metodo è disponibile con questa versione di firebase api

questa è la versione che devi importare da Gradle

compile 'com.google.firebase:firebase-messaging:10.2.1'

questo è il metodo

@Override
public void handleIntent(Intent intent) {
    super.handleIntent(intent);

    // you can get ur data here 
    //intent.getExtras().get("your_data_key") 


}

con la precedente firebase api questo metodo non era presente, quindi in questo caso la base di fuoco si gestisce da sola quando l'app è in background .... ora hai questo metodo qualunque cosa tu voglia fare ... puoi farlo qui in questo metodo .. ...

se stai utilizzando una versione precedente di quella che inizierà l'attività predefinita in quel caso puoi ottenere i dati allo stesso modo

if(getIntent().getExtras() != null && getIntent().getExtras().get("your_data_key") != null) {
String strNotificaiton = getIntent().getExtras().get("your_data_key").toString();

// fai quello che vuoi ....}

generalmente questa è la struttura dal server che riceviamo in notifica

{
    "notification": {
        "body": "Cool offers. Get them before expiring!",
        "title": "Flat 80% discount",
        "icon": "appicon",
        "click_action": "activity name" //optional if required.....
    },
    "data": {
        "product_id": 11,
        "product_details": "details.....",
        "other_info": "......."
    }
}

sta a te come vuoi dare quella chiave di dati o vuoi dare una notifica qualsiasi cosa tu possa dare ....... quello che mai darai qui con la stessa chiave otterrai quei dati ........ .

ci sono alcuni casi in cui non si invia un'azione di clic in quel caso quando si farà clic sull'attività predefinita di notifica si aprirà, ma se si desidera aprire la propria attività specifica quando l'app è in background, è possibile chiamare la propria attività da questo sul metodo handleIntent perché questo viene chiamato ogni volta


Ho aggiornato il firebase-messaging alla 10.2.1, ho aggiunto i dati al messaggio di notifica e ha funzionato. Primo piano, sfondo e ucciso. Grazie
Firas Shrourou il

in Kotlin, ottengo questo errore: (44, 5) 'handleIntent' in 'FirebaseMessagingService' è definitivo e non può essere sostituito
ugali soft

Non funziona sopra le versioni di firebase 11
venu46

14

Secondo i documenti: 17 maggio 2017

Quando l'app è in background , Android indirizza i messaggi di notifica sulla barra delle applicazioni. Un tocco dell'utente sulla notifica apre l' app di avvio per impostazione predefinita .

Ciò include i messaggi che contengono sia payload di notifica che dati (e tutti i messaggi inviati dalla console di notifica). In questi casi, la notifica viene recapitata nella barra delle applicazioni del dispositivo e il payload dei dati viene consegnato negli extra dell'intento dell'attività di avvio.

Quindi, dovresti usare entrambi i dati + la notifica del payload:

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}

Non è necessario utilizzare click_action. Dovresti semplicemente ottenere exras dall'intento sull'attività di LANCIO

<activity android:name=".MainActivity">
        <intent-filter>
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity>

Il codice Java dovrebbe essere sul metodo onCreate su MainActivity:

Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) {
    Bundle extras = intent.getExtras();
    String someData= extras.getString("someData");
    String someData2 = extras.getString("someData2");
}

Puoi testare sia la notifica del payload + i dati dalla Console di notifica Firebase . Non dimenticare di compilare campi di dati personalizzati nella sezione Opzioni avanzate


14

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 nell'area di notifica. Se l'app è in primo piano, i messaggi vengono gestiti onMessageReceived()o didReceiveRemoteNotificationrichiamati. 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 di dati può essere recuperato nell'intento utilizzato per avviare la tua 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, ilclick_action parametro 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 onMessageReceivedmetodo (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.

Per maggiori informazioni visita il mio questo thread



8

Riepilogo semplice come questo

  • se la tua app è in esecuzione;

    onMessageReceived()

è trigger.

  • se la tua app non è in esecuzione (uccisa dallo scorrimento);

    onMessageReceived()

non è attivato e consegnato da Direclty. Se hai una coppia chiave-valore specifica. Non funzionano perché onMessageReceived () non funziona.

L'ho trovato in questo modo;

Nella tua attività di avvio, inserisci questa logica,

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState, R.layout.activity_splash);

    if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("PACKAGE_NAME")) {

        // do what you want

        // and this for killing app if we dont want to start
        android.os.Process.killProcess(android.os.Process.myPid());

    } else {

        //continue to app
    }
}

in questo blocco if, cerca le tue chiavi in ​​base all'interfaccia utente Firebase.

In questo esempio la mia chiave e valore come sopra; (scusa per la lingua =)) inserisci qui la descrizione dell'immagine

Quando il mio codice funziona, ottengo "com.rda.note".

android.os.Process.killProcess(android.os.Process.myPid());

con questa riga di codice, ho chiuso la mia domanda e ho aperto Google Play Market

happy coding =)


6

Ho capito gli scenari,

Quando l'app è in primo piano , il metodo onMessageReceived () viene chiamato da FirebaseService . Quindi il pendingIntent verrà chiamato definito nella classe di servizio.

E quando l'app è in background , viene chiamata la prima attività .

Ora, se si utilizza un'attività splash , è necessario tenere presente la splasattività sarà chiamato, altrimenti se non c'è splashActivity, quindi qualunque sia la prima attività è, sarà chiamato.

Quindi devi controllare getIntent () di firstActivity per vedere se ha qualche pacchetto. Se tutto va bene vedrai che il pacchetto è lì con i valori inseriti. Se il valore nel tag di dati inviato dal server è simile al seguente,

"data": {
    "user_name": "arefin sajib",
    "value": "user name notification"
  }

Quindi nella prima attività, vedrai, c'è un intento valido ( getIntent () non è null ), un bundle valido e un bundle interno, ci sarà l'intero JSON sopra menzionato con i dati come chiave .

Per questo scenario, il codice per l'estrazione del valore sarà simile al seguente,

    if(getIntent()!=null){
            Bundle bundle = getIntent().getExtras();
            if (bundle != null) {
                try {
                   JSONObject object = new JSONObject(bundle.getStringExtra("data"));
String user_name = object.optString("user_name");

                } catch (JSONException e) {
                    e.printStackTrace();
                }


            }
        }

3

Grazie a tutti voi per le vostre risposte. Ma ho risolto questo inviando un messaggio di dati invece di inviare una notifica . Codice del server

<?php
$url = "https://fcm.googleapis.com/fcm/send";
$token = "C-l6T_a7HouUK****";
$serverKey = "AAAAaOcKS00:********";
define( 'API_ACCESS_KEY', $serverKey );
$registrationIds = array($token);
// prep the bundle

$msg = array

(
 'message'  => 'here is a message. message',
 'title'        => 'This is a title. title',
 'subtitle' => 'This is a subtitle. subtitle',
 'tickerText'   => 'Ticker text here...Ticker text here...Ticker text 
 here',
 'vibrate'  => 1,
 'sound'        => 1,
 'largeIcon'    => 'large_icon',
 'smallIcon'    => 'small_icon'

);

$fields = array

(
  'registration_ids'    => $registrationIds,
  'data'            => $msg

);
$headers = array

(
  'Authorization: key=' . API_ACCESS_KEY,
 'Content-Type: application/json'

);


$ch = curl_init();

curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' 
);

curl_setopt( $ch,CURLOPT_POST, true );

curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );

curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );

curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );

curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );

$result = curl_exec($ch );

curl_close( $ch );

echo $result;

?>

E catturato i dati in onMessageReceived

public class MyFirebaseMessagingService extends FirebaseMessagingService     {

  private static final String TAG = "MyFirebaseMsgService";

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

      sendNotification(remoteMessage.getData().get("message"));
     }
   // Check if message contains a notification payload.
    else if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    sendNotification(remoteMessage.getNotification().getBody());
    }


}
   private void sendNotification(String messageBody) {
    Intent intent = new Intent(this, Notify.class).putExtra("msg",messageBody);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

    String channelId = "idddd";
    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(MyFirebaseMessagingService.this)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("FCM Message")
                    .setContentText(messageBody)
                    .setAutoCancel(true)
                    .setSound(defaultSoundUri)
                    .setContentIntent(pendingIntent);

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}

1
funziona anche con uno sfondo?
Tabish khan,

@Tabishkhan Sì fratello funziona se hai qualche problema sentiti libero di chiedermelo .. grazie
Android Sanaullah

1
ciao @AndroidSanaullah, puoi spiegare la prima parte del codice del server, dove lo metti effettivamente, sto affrontando lo stesso problema ma non capisco bene la parte del server, stai usando postino?
Shid

curl viene utilizzato per la richiesta e tutti i parametri vengono passati ad essa. @ Shid
Android Sanaullah

2

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

Ecco cosa sto inviando dal server:

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

Quindi puoi ricevere i tuoi dati in onMessageReceived(RemoteMessage message)questo modo: (diciamo che devo ottenere l'id)

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

Allo stesso modo puoi ottenere tutti i dati che hai inviato dal server all'interno onMessageReceived().


2

Il modo più semplice per inviare messaggi anche se l'app è in background e in primo piano come segue: - Per inviare un messaggio utilizzando l'API, puoi utilizzare uno strumento chiamato AdvancedREST Client, è un'estensione di Chrome e inviare un messaggio con i seguenti parametri.

Link strumento client di riposo: https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo

usa questo url: - https://fcm.googleapis.com/fcm/send Tipo di contenuto: application / json Autorizzazione: chiave = chiave del server Da o chiave di autorizzazione (vedi sotto rif)

{ "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"
}

La chiave di autorizzazione può essere ottenuta visitando la console degli sviluppatori di Google e facendo clic sul pulsante Credenziali nel menu a sinistra per il progetto. Tra le chiavi API elencate, la chiave del server sarà la chiave di autorizzazione.

E devi inserire il tokenID del destinatario nella sezione "a" della tua richiesta POST inviata utilizzando l'API.


2

vuoi lavorare suMessageReceived (RemoteMessage remoteMessage) in background invia solo la notifica della parte di dati parte questo:

"data":    "image": "",    "message": "Firebase Push Message Using API", 

"AnotherActivity": "True", "to": "ID dispositivo o token dispositivo"

Con questo onMessageRecivied si chiama background e in primo piano non è necessario gestire la notifica utilizzando il vassoio di notifica sull'attività di avvio. Gestisci il payload dei dati usando questo:

  public void onMessageReceived(RemoteMessage remoteMessage)
    if (remoteMessage.getData().size() > 0) 
    Log.d(TAG, "Message data payload: " + remoteMessage.getData());      

1

Risposta di giugno 2018 -

Devi assicurarti che non ci sia una parola chiave "notifica" in nessun punto del messaggio. Includi solo "dati" e l'app sarà in grado di gestire il messaggio in onMessageReceived, anche se in background o ucciso.

Utilizzo delle funzioni cloud:

const message = {
    token: token_id,   // obtain device token id by querying data in firebase
    data: {
       title: "my_custom_title",
       body:  "my_custom_body_message"
       }
    }


return admin.messaging().send(message).then(response => {
    // handle response
});

Quindi nel tuo onMessageReceived (), nella tua classe estendendo com.google.firebase.messaging.FirebaseMessagingService:

if (data != null) {
  Log.d(TAG, "data title is: " + data.get("title");
  Log.d(TAG, "data body is: " + data.get("body");
}

// build notification using the body, title, and whatever else you want.

hai qualche fonte, è sicuro?
Yogesh Rathi,

È sicuro, lo uso nelle mie app. Tuttavia, a 6 mesi dalla pubblicazione, non ricordo la fonte: immagino sia la documentazione di base.
Jeff Padgett,

1

Secondo OAUTH 2.0:

Ci sarà un problema di Auth per questo caso perché FCM ora usa OAUTH 2

Quindi ho letto la documentazione di Firebase e secondo la documentazione è un nuovo modo di inviare un messaggio di dati;

POST: https://fcm.googleapis.com/v1/projects/YOUR_FIREBASEDB_ID/messages:send

intestazioni

Key: Content-Type, Value: application/json

auth

Bearer YOUR_TOKEN 

Corpo di esempio

{
   "message":{
    "topic" : "xxx",
    "data" : {
         "body" : "This is a Firebase Cloud Messaging Topic Message!",
         "title" : "FCM Message"
          }
      }
 }

Nell'URL c'è l'ID database che puoi trovare sulla tua console firebase. (Vai impostazioni del progetto)

E ora prendiamo il nostro token (sarà valido solo 1 ora):

Innanzitutto nella console di Firebase, apri Impostazioni> Account di servizio . Fai clic su Genera nuova chiave privata , archivia in modo sicuro il file JSON contenente la chiave. Avevo bisogno di questo file JSON per autorizzare manualmente le richieste del server. L'ho scaricato.

Quindi creo un progetto node.js e ho usato questa funzione per ottenere il mio token;

var PROJECT_ID = 'YOUR_PROJECT_ID';
var HOST = 'fcm.googleapis.com';
var PATH = '/v1/projects/' + PROJECT_ID + '/messages:send';
var MESSAGING_SCOPE = 'https://www.googleapis.com/auth/firebase.messaging';
var SCOPES = [MESSAGING_SCOPE];

  router.get('/', function(req, res, next) {
      res.render('index', { title: 'Express' });
      getAccessToken().then(function(accessToken) {
        console.log("TOKEN: "+accessToken)
      })

    });

function getAccessToken() {
return new Promise(function(resolve, reject) {
    var key = require('./YOUR_DOWNLOADED_JSON_FILE.json');
    var jwtClient = new google.auth.JWT(
        key.client_email,
        null,
        key.private_key,
        SCOPES,
        null
    );
    jwtClient.authorize(function(err, tokens) {
        if (err) {
            reject(err);
            return;
        }
        resolve(tokens.access_token);
    });
});
}

Ora posso usare questo token nella mia richiesta di post. Quindi inserisco il mio messaggio di dati, che ora è gestito dalle mie app sulla funzione Messaggio ricevuto.


La risposta accettata funziona, l'autenticazione token barer non è il modo giusto, devi leggerlo per provarlo con Postman: stackoverflow.com/questions/45309674/…
Carlos Jesus Arancibia Taborga

1

Dal 2019, Google Firebase ha un grande cambiamento nelle loro API, intendo: 'com.google.firebase:firebase-messaging:18.0.0'

in 18.0.0 sono stati rimossi MyFirebaseInstanceIDServicee devi ottenere il token, MyFirebaseMessagingServicequindi devi solo scrivere:

@Override
public void onNewToken(String token) {
    Log.d(TAG, "Refreshed token: " + token);

}

e anche nel tuo AndroidManifest.xml, devi rimuovere:

<service android:name=".service.MyFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

Inoltre, si consiglia di impostare i valori predefiniti per personalizzare l'aspetto delle notifiche. È possibile specificare un'icona predefinita personalizzata e un colore predefinito personalizzato che vengono applicati ogni volta che non vengono impostati valori equivalenti nel payload di notifica.

Aggiungi queste righe all'interno del tag dell'applicazione per impostare l'icona predefinita personalizzata e il colore personalizzato:

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_notification" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/colorAccent" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/push_channel" />

ora per gestire i messaggi di notifica in un'app in background è necessario definire un Intento nella prima attività anche se si tratta di SplashScreen, quando l'app è in background, Android indirizza i messaggi di notifica nella barra delle applicazioni. Un tocco dell'utente sulla notifica apre l'app di avvio per impostazione predefinita.

per esempio, se il tuo Json è così:

 "data": {
"message": "2",
"title": "1",
"pushType" : "banner",
"bannerLink": "http://www.google.com",
"image" : "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"}

devi solo scrivere un semplice intento per ottenere quei valori:

        Bundle extras = intent.getExtras();
        String bannerLink = extras.getString("bannerLink");
        ...
        String channelId = extras.getString("channelId");

0

Oltre alle risposte precedenti, se si stanno testando le notifiche push utilizzando la console FCM , la chiave e l'oggetto "dati" non lo sono aggiunti al pacchetto Notifiche push. Quindi non riceverai una notifica push dettagliata quando l'app è in background o uccisa.

In questo caso devi optare per la tua console di amministrazione back-end per testare lo scenario di sfondo dell'app.

Qui avrai aggiunto la chiave "dati" al tuo pacchetto push. così, la spinta dettagliata verrà mostrata come previsto. Spero che questo aiuti pochi.


0

Usando questo codice puoi ottenere la notifica in background / in primo piano e anche mettere un'azione:

//Data should come in this format from the notification
{
  "to": "/xyz/Notifications",
  "data": {
      "key1": "title notification",
      "key2": "description notification"
  }
}

In-App usa questo codice:

  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
      String key1Data = remoteMessage.getData().get("key1");
      // use key1Data to according to your need
    }

// I dati dovrebbero venire in questo formato dalla notifica {"a": "/ xyz / Notifiche", "dati": {"chiave1": "notifica titolo", "chiave2": "notifica descrizione"}} Come scrivere questo codice nel servizio php?
Tabish khan,

-3

Ci saranno due tipi di notifiche

  1. Visualizza notifica: verranno visualizzate solo le notifiche, verrà mostrata solo l'app non è aperta e si trova nello stack dell'app.
  2. Notifica dati: la richiamata entrerà nel metodo onMessageReceived di firebasemessagingservice e funziona quando l'app è in background, in primo piano o in stato di interruzione.

È necessario utilizzare Notifiche dati per gestire la notifica quando l'app è in background.


-5

Ho riscontrato lo stesso problema e ho ricompilato la libreria firebase e gli ho impedito di inviare notifiche quando l'applicazione è in background

* libreria https://github.com/erdalceylan/com-google-firebase-messaging

 dependencies {
        compile 'com.google.firebase:firebase-core:11.2.0'
        compile 'com.github.erdalceylan:com-google-firebase-messaging:v1-11.2.0'
    }

*

@WorkerThread
public void onMessageReceived(RemoteMessage var1) {
  //your app is in background or foreground all time calling
}

la speranza aiuta. In bocca al lupo


2
Risposta non utile
Ankit Patidar,

2
Questo è un suggerimento orribile.
vsecades,
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.