Receiving FCM (Firebase Cloud Messaging) messages in an Android service whilst the app is not running

As per the subject, has anyone had any luck getting an app to receive FCM notifications directly in an Android service whilst the app itself isn’t running?

I’ve spent quite a bit of time searching, but haven’t found anything to do what I want. The closest that I’ve found is the FCMRebooted demo by Dave Nottage (thanks Dave!) here:

With this demo, I can start the app and then swipe it away so that it’s no longer active and still have messages posted to the system log indicating that the sample service is receiving “data” FCM messages. The issues with this is that the service appears to be created fresh each time, so doesn’t have the ability to retain any state information. I’m guessing that I could set up a separate service that does run all the time and send messages to it with a broadcast intent - I haven’t spent much time looking at that yet though.

The bigger problem with this demo is that it always shows a notification to the user - I’m wanting the notifications to be invisible to the user normally - if the app does need to get the attention of the user, I’m planning for it to go the whole hog like an incoming phone call - screen on, vibrating and playing sound. I’m guessing that the notifications that are popping up are a feature of the Kastri JAR files that the demo is using to route the FCM messages to the service - I can’t see any way to modify those files myself.

Coming from a different angle, I’ve followed the instructions on the Embarcadero page here:
https://docwiki.embarcadero.com/RADStudio/Sydney/en/Firebase_Android_Support

This allows me to silently receive FCM data messages when my app is active and also when it’s running in the background, however, if the app is swiped closed, it no longer receives any notifications.

Trying to move the code into a foreground service so that it survives the app being swipe closed hasn’t been a success: FMX.PushNotification.Android pulls in other FMX units which then means that the service doesn’t start properly since you can’t use FMX units in Android services. I have successfully modified FMX.PushNotification.Android to remove the dependencies on FMX units without breaking it - the modified unit still works in the main app. Trying to include it in the Android service though just leads to no messages being received - it does get the OnServiceConnectionChange event fired and it gets the same token as the main app, but still no dice. Interestingly, if I leave my NoFMX.PushNotification.Android unit in the uses clause of my service, the main app is also no longer able to receive notifications as well.

I’ve contemplated modifying the AndroidManifest.xml file to include an Intent Filter for my service as well as and/or in place of the intent filter that Delphi is adding in, but my expectation is that it’s not going to work still due to the way that FCM messages are routed through the proxy service that it appears is being silently included.

Thanks in advance to anyone that can help with this.

What exactly do you want to solve in this case?

I could make this an option, i.e. that the notification is not presented under certain circumstances.

Again, can you describe what you are trying to solve by keeping something running? Android (as well as iOS) are very unforgiving when attempting to have something running all the time - usually whatever it is can be solved by triggering code only when certain things happen, which is why it’s important to describe exactly what you want the code to do, and the why may help also.

In a nutshell, I’m wanting a way to alert the user to fairly time sensitive events without putting too much of a drain on the phone battery. Ideally, I’d like to alert the user as quickly as possible - generally no more than a few seconds at most if possible. At the moment, I’ve got a solution that works as far as showing a standard notification to the user by having a foreground Android service running all the time which maintains a TCP connection to my server. The issue with this is that it puts a fairly significant drain on the phone battery - around 2-3% per hour without the phone actually being used. Battery use is higher on WiFi than on a mobile connection - presumably because mobile networks are better optimised to reduce battery use than WiFi networks.

Due to the sometimes critical nature of these alerts and not totally trusting the Google FCM service, I’d like to send regular FCM messages to confirm that it’s working and have the Android app go to a fallback connection if messages stop coming through.

That would be awesome if you can do that.

Hopefully this should be a pretty easy job for you to do, but I’ll contact you directly to discuss making a donation to cover your time and also as a thank you for all of the other work that you’ve done with Kastri/mobile app development.

I suppose that I could just have the service that receives the notification perform whatever action needs to be taken directly instead of having it send a message to an actively running service and have it do the work. Any required state information could be retrieved from the file system - where other apps can’t access it. It does seem a bit inefficient to have to recreate everything each time, but I suppose the normal use case would be for only intermittent messages, so I’ll just have to live with what can be done.

Just an update for anyone wanting to handle notifications without alerting the user, David updated his Kastri library to allow for this earlier this afternoon - I’ve since tested it and confirmed that it works - thanks Dave - donation duly sent through. :slight_smile:

3 Likes

2 posts were split to a new topic: License agreements