Firebase push notification
firebase fcm push kotlin android tutorial Estimated reading time: 10 minutesInforming users about some events it’s an almost essential part of any modern mobile app. On both most popular platforms (iOS, and Android) we can integrate push notifications - something small and intuitive for users, something that can bring a part of the u’r app closer and faster to the user.
Integration of this functionality can be a bit tricky, especially if u do this for the first time.
With iOS I have a rich experience of how to do that, but on Android, there are a few additional moments that need to know before we can make it live for all cases.
use-cases
Before actual implementation, we should understand all possible use cases for push notifications. This will make the app very responsive and provide the best UX for the user.
Under use cases, I mean something from a tech aspect - a moment from which the user can receive the notification.
Here are a list of moments that u definetly needs to handle when u deal with push notifications:
- app is not running
- app is running
- app is foreground active
- on destination screen
- not on destination screen
- app is foreground inactive (backround)
- on destination screen
- not on destination screen
- app is foreground active
Whoo - all started from a simple push idea. Of cause - if push informative - all is much easier, but if it requires some action or contains a deep link - than, that’s the true story.
there are a few more use-cases, and also some of them can be added due to u’r logic in the app, but, in general, this is the basic list of what u need to handle at a minimal level when u work with push
integration
Integration should be started from official documentation where u can find all the steps needed for integration fcm-push. This is a good moment, the bad one - not all aspects are covered. Due to this, I will put here step-by-step instructions.
firebase console
The very first step would be registration on firebase console.
Create a new project and add a new app to it. Just follow the next-next flow. The important point here - is to use u’r real package name as u specified in the project. On one of the steps, google-services.json
will be generated - u need to include this file into the u’r project src
directory - this file will be used by firebase services.
A good moment here - if u want to have different channels for debug/release build - just create a same-name folder in the
src
directory and place 2 differentgoogle-services.json
- one for a separate app: debug and release:
SDK
Now, needs to add SDK to the project.
Open build.gradle
for project lvl and add classpath:
In module build.gradle
add dependencies:
Press sync now.
Run the project, on console u will see success message:
FirebaseMessagingService
Now, it’s time to configure FirebaseMessagingService
- a service for handling the received notifications. Open AndroidManifest.xml
in app/manifests
and add this config:
where AuthFirebaseMessagingService
is a subclass of the FirebaseMessagingService
.
we also can add a custom icon/color for notification - for that, add config in the same file under service registration:
more info u can find here
AuthFirebaseMessagingService
- for now, just create a class with no implementation:
Before we go to the actual implementation - it’s good to understand what we want to achieve. By default, push notifications will be shown with a default icon and minimal behavior. But often, we need to save fcm-token (for example to send on the server, for scheduling push and associating it with concrete user). Also, if we want to handle interaction on push (like a deep link) we must parse the payload and process it. All these moments will dictate the logic we need.
Inside AuthFirebaseMessagingService
let’s create s function for retriving fcm-token:
Sometimes fcm-token can be updated (depends on the firebase lifecycle), so to always get an actual version of this token we must override the function in FirebaseMessagingService
:
And of cause, one more important callback to override - it’s on onMessageReceived(remoteMessage:)
- place where we got raw payload:
u may also want to check the possibility for android devices to receive push notifications. For that, u can use the next function
test notification
To send notifications we can use the Firebase console - step-by-step instructions will tell u how to configure push content.
To send on u’r device - use obtained token in same menu:
handling payload
Now, the most interesting part - handling the payload. As I mention at the beginning of the article - there are a lot of cases to work with.
The good moment - is that part of the logic will be shared in between the cases.
Let’s review the most complex example - the user clicks on the notification, and if the payload contains some data, an appropriate deep link is triggered with the received payload as an input parameter.
To simplify this, we can divide the process into separate steps:
- receive a token (done)
- configure received push and parsing payload
- parse payload
- receive model as param
- deep link (with a model as param)
- show screen
As I mention in the list, the first step we already did. Now we should parse the payload.
When I receive push, the complete payload looks like this:
The tricky moment here - is that if we parse the push payload, we are responsible for displaying this push. To do so, we can create a separate function for that:
sendNotification(messageBody:,bundle:)
called from theonMessageReceived(remoteMessage:)
Here I used an extension for NotificationManager
- the heart of our push-displaying logic. Indeed this function configures deep links, notification channels, images, color (and other appearance stuff).
full code of service and extention
The last moment we need to do - is to show the screen when the user presses the push that contains a deep link.
Here is a tricky moment - u need to handle 2 cases for the same situation - when the app is launched and when not. Depending on this u either inject data intro flow or either system will provide this data via extras
from firebase service (the one that we created).
Notice from the code that we re-schedule notification with additional params:
This Bundle
will be parsed as soon as we perform navigation.
So let’s review these 2 cases in detail:
running app
If u run the app, then we just perform navigation to the selected screen:
The important moment here is that our navigation graph contains fragments with input params:
Then, as soon as the app navigates us via nav_graph to the target screen, onActivityCreated(savedInstanceState:)
method is invoked and we can obtain our object:
The result:
not-running app
With not running the app we can’t use this approach - our nav_graph does not exist yet, nothing is holding fragments yet, and nothing can transfer data. For this case, we should use extras.
What we need to do - is to check extras on the start app, and if there is something (in our case model received from push payload), then we should navigate.
To do so, we can do something as follows:
intent.extras
is just a Bundle
that we can check for some data. All the rest - is just a navigation and model transfer to the screen.
Off cause, u may have some additional logic (like checking if a user is still logged in or if the screen is protected with a touch id, etc). Such situations must be handled in addition.
The good moment for checking extras
- onCreate(savedInstanceState:)
of target activity:
conclusion
Push notification is a great way to notify u’r users with some info. But always remember that this is an optional way and so can be always disabled by the user.
Using firebase push is easy and well configurable for u’r needs. U may read even more about notifications themselves and various way of configurations.
resource
Share on: