3

I need to be able to send my GPS-location to a server every time I receive a silent-push notification from Firebase. The timer for sending a notification is currently set to every 10 minutes. When the phone is charging this is not a problem, but when it's idle and the application is in the background, the onMessageReceived from FirebaseMessagingService is only called every few hours. This leads me to believe it has something to do with the new power management rules for Android 9.0. But for my application to work I need to be able to send my location every 10 minutes. Not just sometimes.

I have tried to set the battery optimisation to 'not optimised' using Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
This does not seem to have any effect.

I also tried setting the priority of the Firebase notification to High. This works, but only for 10 messages per day, which means it's not a solution for my application. (Source: Power Management restrictions)

I am now trying to always have the application in the 'Active' bucket by opening a foregroundService. This should make sure the app is never in any other bucket, where the notifications can be deferred for a few hours.

An app is in the active bucket if the user is currently using the app, for example:

  • The app has launched an activity
  • The app is running a foreground service
  • The app has a sync adapter associated with a content provider used by a foreground app
  • The user clicks on a notification from the app

If an app is in the active bucket, the system does not place any restrictions on the app's jobs, alarms, or FCM messages.

(Source: Power Buckets Android9).

This does not seem like a solution I should want, though, since it might not be best practice. And it doesn't seem to work either anyways.

This is my onMessageReceived function:

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

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

        Map<String, String> params = remoteMessage.getData();
        JSONObject object = new JSONObject(params);

        PushNotificationManager.getInstance().handlePushNotification(object, getApplicationContext());
    }
}

Right now I am clueless as to why the Firebase messages do not enter the onMessageReceived function.

Community
  • 1
  • 1
Tim 1
  • 31
  • 5

2 Answers2

1

Tim, I think that the main problem is with how you send the push notification and what is its content. If you check here - https://firebase.google.com/docs/cloud-messaging/android/receive you will see that if the message contains notification data and the app is at background then the push notification goes to the Notification area. You need to send a push notification that contains only data: (Here you can find more information about the different types - https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages) Here is what is the explanation how to trigger it- In a trusted environment such as Cloud Functions or your app server, use the Admin SDK or the FCM Server Protocols: Set the data key only.

Please note that if you need to do a long running operation, then you will need to start a separate service (the service should present a notification in the notification area that it is running, otherwise you will get a crash on the newer Android versions)

  • Hi Yani. Thank you for your answer, but I don't think it is a solution. When we send a request from Firebase we send only a data message, which will always go in the onMessageReceived. I know the message doesn't enter the onMessageReceived at all because I log the remoteMessage.getFrom() before executing any other code, and sadly it doesn't show up in my logs. – Tim 1 Jul 01 '19 at 13:55
0

Fixed by using AlarmManager. Schedule an alarm in 10 minutes, and when completing the code within the alarm, schedule a new alarm in 10 minutes.

AlarmManager can wake the phone if it is in doze mode, which means all code inside the trigger will be executed properly.

Tim 1
  • 31
  • 5