androidfirebase-cloud-messagingvoip

Firebase cloud messaging lowers messages priority on Android


I develop calling application. Every incoming call in our application starts with HIGH priority push (Firebase Cloud Messaging). After upgrading our targetSdk to 31 (Android 12) we started to get too much crashes with message:

Fatal Exception: java.lang.RuntimeException: Unable to create service com.example.CallsConnectionService: android.app.ForegroundServiceStartNotAllowedException: Service.startForeground() not allowed due to mAllowStartForeground false: service com.example.callingpp/com.example.CallsConnectionService

CallsConnectionService - is a service which implements ConnectionService (from TelecomManager API). Our application starts this service after getting information about new incoming call. And sometimes (only when app is in background) when our app starts this service it crashes with message above.

I've found, that it crashes mostly because of incoming call push notification priority. It is NORMAL instead of HIGH. Android 12 forbids to start services from background when getting NORMAL pushes. It allows to do it only for HIGH pushes. When I discovered this information I started to look for what can lead to lower priorities. I found, that Firebase lowers priorities for the app if the app getting HIGH pushes and not displaying notifications right away. I've collected analytics about lowering priority in our app from production: ~16% of all HIGH pushes getting lower priority in production.

In our app we have only four types of HIGH notifications: new incoming call, new incoming message, new voicemail message, new missed call. We always displaying notifications for all, except incoming call. When our application gets incoming call notification it is doing some internal work to connect to the PBX server and get information about this call. It can be happened, that our server returns nothing about call, because it was answered already on other device, or because it was already canceled by caller. For this cases our application shows nothing for HIGH priority push. So it can lead to lowering priorities in future for device and app.

The question is: how to beat this issue? Which notification should we show during this incoming call clarification process to avoid Firebase lowering priority in the future?

P.S. I've added simple notification (notification with text, without any action buttons) after every incoming call push, the text on notification was "Incoming call preparation", but it does not help. We see, that we are still getting about 16% of lowering priority for HIGH notifications in production.


Solution

  • When you have fcm message with LOW priority and want to run some foreground services in a background you will get this exception (it is described here).

    Notice, that RemoteMessage.originalPriority can be HIGH, but RemoteMessage.priority (actual priority) can be LOW. This is called deprioritization (or lowering priority).

    So, here are the reasons why lowering priorities happen:

    What you need to do to work with this:

    There is also some unbeatable issue with HIGH notifications: delays. HIGH notifications can be delayed for unknown time because of offline (you can check how many your HIGH notifications were delayed here). It does not lead to lowering priorities, but you also have to think about it, and show to the user some info like this: 'We received important message in a background, but we received it too late (probably because of offline). Please see it.'. You may use RemoteMessage.sentTime for getting actual time when notification was sent to the device.