4

I am sending fcm notifications to my app from server.

I am sending data from server which contains user_id. I am getting this userId in FirebaseMessageService class if app is in foreground. But Not getting it when the app is in background. As FirebaseMessagingService class only gets execute when the app is in foreground.

So how can I get this id when the app is in background?

    public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";
    private String mUserId;
    private Boolean mUpdateNotification;

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        //Displaying data in log
        //It is optional
        Log.d(TAG, "From: " + remoteMessage.getFrom());
        Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());

        String clickAction = remoteMessage.getNotification().getClickAction();

        mUserId = remoteMessage.getData().get("user_id");

        String title = remoteMessage.getNotification().getTitle();

        //Calling method to generate notification
        sendNotification(remoteMessage.getNotification().getBody(),clickAction,title);
    }

    //This method is only generating push notification
    //It is same as we did in earlier posts
    private void sendNotification(String messageBody,String clickAction,String title) {

        mUpdateNotification = true;

        Intent intent = new Intent(clickAction);

        intent.putExtra("userId",mUserId);
        intent.putExtra("updateNotification",mUpdateNotification);

        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle(title)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

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

        notificationManager.notify(0, notificationBuilder.build());
    }
}

EDIT:

I am using data payload still onMessageReceived dose not get called when app is in background.

 public function sendPush($text, $tokens, $apiKey,$user_id)
{

    $notification = array(
        "title" => "User updated profile.",
        "text" => $text,
        'vibrate' => 3,
        "click_action" => "OPEN_ACTIVITY_2",
        'sound' => "default",
        'user_id' => $user_id
    );

    $data = array("user_id" => $user_id);

    $msg = array
    (
        'message' => $text,
        'title' => 'User updated profile.',
        'tickerText' => 'New Message',
    );
    $fields = array
    (
        'to' => $tokens,
        'data' => $data,
        'notification' => $notification
    );

    $headers = array
    (
        'Authorization: key=' . $apiKey,
        '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);
    //  echo($result);
    //    return $result;
    curl_close($ch);
}

Can anyone help with this please? Thank you..

AL.
  • 36,815
  • 10
  • 142
  • 281
Sid
  • 2,792
  • 9
  • 55
  • 111
  • If you're only using `data` payload, pretty sure that it is only received in `onMessageReceived` regardless if the app is in foreground or background. See https://firebase.google.com/docs/cloud-messaging/android/receive – AL. Oct 18 '16 at 12:00
  • Please check edited question. @AL. – Sid Oct 18 '16 at 12:14

2 Answers2

17

I see. In your payload you are using both notification and data payload, which changes where you're supposed to receive the details when the app is in background. In the doc I mentioned in the comments, you can see in the summary if both are included in the payload:

Data: in extras of the intent.

More specifically:

Handle notification messages in a backgrounded app

When your app is in the background, Android directs notification messages to the system tray. A user tap on the notification opens the app launcher by default.

This includes messages that contain both notification and data payload (and all messages sent from the Notifications console). In these cases, the notification is delivered to the device's system tray, and the data payload is delivered in the extras of the intent of your launcher Activity.

I think this answer by @ArthurThompson explains it very well:

When you send a notification message with a data payload (notification and data) and the app is in the background you can retrieve the data from the extras of the intent that is launched as a result of the user tapping on the notification.

From the FCM sample which launches the MainActivity when the notification is tapped:

if (getIntent().getExtras() != null) {
    for (String key : getIntent().getExtras().keySet()) {
        String value = getIntent().getExtras().getString(key);
        Log.d(TAG, "Key: " + key + " Value: " + value);
    }
}
Community
  • 1
  • 1
AL.
  • 36,815
  • 10
  • 142
  • 281
0

Register your service in manifest

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

you can check app is in Foreground or not

    public static boolean CheckAppIsRunningForground(Context mcontext) {

    ActivityManager am = (ActivityManager) mcontext
            .getSystemService(mcontext.ACTIVITY_SERVICE);

    // get the info from the currently running task
    List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);

    ComponentName componentInfo = taskInfo.get(0).topActivity;
    if (componentInfo.getPackageName().equalsIgnoreCase(<YOUR PACKAGE>)) {
        return true;
    } else {
        return false;
    }

}

and add this code inside onMessageReceived

    Boolean IsForground = CheckAppIsRunningForground(AgentService.this);
    if (IsForground) {

                  //App is FourGround

                } else {
                     sendNotification(remoteMessage.getNotification().getBody(),clickAction,title);
                }
Ganesh Pokale
  • 1,538
  • 1
  • 14
  • 28
  • and in which class checkkAppIsRunningForeground method should be added ?@Ganesh Pokale – Sid Oct 18 '16 at 10:48
  • you can add this in MyFirebaseMessagingService – Ganesh Pokale Oct 18 '16 at 10:49
  • 2
    but MyFirebaseMessagingService this class dose no get called na when app is in background? – Sid Oct 18 '16 at 10:52
  • I have registered service in manifest. It gets called when app is in foreground gives me the user id but not when the app is in background.@Ganesh Pokale – Sid Oct 18 '16 at 11:03
  • Ok, put your app in background and send one message from server and add stacktrace here – Ganesh Pokale Oct 18 '16 at 11:04
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126007/discussion-between-sid-and-ganesh-pokale). – Sid Oct 18 '16 at 11:41