1

As per https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages, I can use data messages which will be 100% received onMessageReceived method and act accordingly. But in my case none of my messages are received when app is killed. Though they are sometimes received when I'm testing on Nexus 5 only. Below is my data payload.

05-16 06:46:01.663 13199-29574/jss.test E/MyFirebaseMsgService: Data Payload: {data={"image":null,"title":"My message"}}
05-16 06:46:01.667 13199-29574/jss.test E/Providerfalse: true
05-16 06:46:01.667 13199-29574/jss.test E/MyFirebaseMsgService: Notification JSON {"data":{"image":null,"title":"My message"}}

Manifest For FCM as below:

 <service
            android:name=".FirebaseMessagingService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

Firebasemessaging service:

  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        if (remoteMessage.getData().size() > 0) {

            Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());
            try {
                JSONObject json = new JSONObject(remoteMessage.getData().toString());
                sendPushNotification(json);
            } catch (Exception e) {
                Log.e(TAG, "Exception: " + e.getMessage());
            }
        }
    }


    //this method will display the notification
    //We are passing the JSONObject that is received from
    //firebase cloud messaging
    private void sendPushNotification(JSONObject json) {
                   //optionally we can display the json into log
        Log.e(TAG, "Notification JSON " + json.toString());
        try {
            //getting the json data
            JSONObject data = json.getJSONObject("data");

            //parsing json data
            String title = data.getString("title");
            String message = data.getString("message");
            String imageUrl = data.getString("image");

//code to call service if message has specific data values.
    }
        catch (Exception e) {
                    e.printStackTrace();    }}

Can you guide where I fix to make it working perfectly.

KENdi
  • 7,576
  • 2
  • 16
  • 31
Panache
  • 1,701
  • 3
  • 19
  • 33

5 Answers5

0

As per my testing in my fcm implementation if I am passing data in both data & notification key then I able to get notification in onMessageReceived method at only application running other wise I am not able to get notification, and If I am using only Data key for send notification then it work in both scenario, So remove notification key if exist in your notification data, and test it, it may be work.

Dhaval Solanki
  • 4,589
  • 1
  • 23
  • 39
0

Try following method it will help you

private void sendNotification(String text, String senderId, String receiverId) {
        HttpsURLConnection conHttp = null;
        try {

            URL url = new URL("https://fcm.googleapis.com/fcm/send");
            conHttp = (HttpsURLConnection) url.openConnection();
            conHttp.setDoOutput(true);
            conHttp.setDoInput(true);
            conHttp.setRequestMethod("POST");
            conHttp.setRequestProperty("Content-Type", "application/json");
            //Put below you FCM API Key instead
            conHttp.setRequestProperty("Authorization", "key="
                    + “YOUR_FCM_API_KEY”);

            JSONObject root = new JSONObject();
            JSONObject data = new JSONObject();
            data.put(KEY_FCM_TEXT, text);
            data.put(KEY_FCM_SENDER_ID, sender);
            root.put("data", data);
            root.put("to", "/topics/user_" + receiverId);

            byte[] outputBytes = root.toString().getBytes("UTF-8");
            OutputStream os = conHttp.getOutputStream();
            os.write(outputBytes);
            os.flush();
            os.close();
            conHttp.getInputStream(); //do not remove this line. request will not work without it gg

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } finally {
            if (conHttp != null) conHttp.disconnect();
        }
    }
Dhaval Solanki
  • 4,589
  • 1
  • 23
  • 39
  • what is sender Id and receiver Id? – Panache May 18 '17 at 13:40
  • applied your code and here is value for data {"KEY_FCM_TEXT":"test","KEY_FCM_SENDER_ID":"4849877"}{"data":{"KEY_FCM_TEXT":"test","KEY_FCM_SENDER_ID":"4849877"},"to":"\/topics\/user_ekBwmk__gzs:APA91bFU6oTveaF0fYNyswVzZ5C8ycghM6A-dmcbMFvojxOHTF_GUoRLhIRD1a89aSgx0QQcADw90NRBxviKlGHK1WLpOJfsxRlgmNKgNT2mlA"} but no notification received on target. Any error in this. – Panache May 18 '17 at 14:18
  • waiting for ur support, – Panache May 19 '17 at 13:31
  • Still I can't Help you just because one of the reason which is I already described you, may be you need to check your device security. – Dhaval Solanki May 22 '17 at 04:19
  • What I found is it works fine with moto, nexus, Asus and some other devices like samsung but not with oppo, vivo, etc. I understand it is security issue with those devices and os settings. But many apps are able to work – Panache May 22 '17 at 04:44
  • One of the reason for other app use, may be they have already permission or other wise they have own Connection. – Dhaval Solanki May 22 '17 at 04:49
0

Define one more thing in your service manifest:

android:stopWithTask="false"

It should be work, Otherwise there is no method to get message from onMessageReceived while app is killed.

nivesh shastri
  • 430
  • 2
  • 13
0

Try using getBody() instead of getData():

    @Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);
    if (remoteMessage.getBody().toString.length() > 0) {

        Log.e(TAG, "Data Payload: " + remoteMessage.getBody().toString());
        try {
            JSONObject json = new JSONObject(remoteMessage.getBody().toString());
            sendPushNotification(json);
        } catch (Exception e) {
            Log.e(TAG, "Exception: " + e.getMessage());
        }
    }
}


//this method will display the notification
//We are passing the JSONObject that is received from
//firebase cloud messaging
private void sendPushNotification(JSONObject json) {
               //optionally we can display the json into log
    Log.e(TAG, "Notification JSON " + json.toString());
    try {
        //getting the json data
        JSONObject data = json.getJSONObject("data");

        //parsing json data
        String title = data.getString("title");
        String message = data.getString("message");
        String imageUrl = data.getString("image");

}
    catch (Exception e) {
                e.printStackTrace();    }}
Ashish Gupta
  • 737
  • 11
  • 18
  • I can use what u suggest but first service should start when app is killed, which it not happening. I added code onCreate to check whether it gets started on notification send, and it did not. how just putting .getbody will work in that case. – Panache May 18 '17 at 14:59
0
public class MyService extends Service {
    public MyService() {
    }
    public int onStartCommand(Intent intent, int flags, int startId) {
       // Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();

        // For each start request, send a message to start a job and deliver the
        // start ID so we know which request we're stopping when we finish the job
       startService(new Intent(getApplicationContext(),          FirebaseMessagingService.class));

        // If we get killed, after returning from here, restart
        return START_STICKY;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
Alex Riabov
  • 8,655
  • 5
  • 47
  • 48
  • Create a service like the above and return STICKY to enabled the service from restarting when your app its killed ,and then you add " startService(new Intent(getApplicationContext(), FirebaseMessagingService.class));" this will start your FirebaseMessagingService .And don't forget to retrieve your Firebase message from data . – Abdul razak Jan 16 '19 at 07:43