Adding the Notification Plugin

Add the breez-sdk dependency to your application's build.gradle file in the app directory.

android {
    defaultConfig {
        // Add a build config field to read the Breez API key 
        // from a git ignored `` file 
        buildConfigField "String", "BREEZ_SDK_API_KEY",'BREEZ_SDK_API_KEY')

    // This might help building if duplicate libraries are found
    packagingOptions {
        pickFirst "lib/armeabi-v7a/"
        pickFirst "lib/arm64-v8a/"
        pickFirst "lib/x86/"
        pickFirst "lib/x86_64/"
        exclude "META-INF/*"

dependencies {
    // Add the breez-sdk dependency
    implementation "com.github.breez:breez-sdk"

Integrate the Notification Plugin

You're ready to add some Kotlin code to implement the Notification Plugin in your application. In the example below, we are using the FirebaseMessagingService to receive the message intents. First, let's implement the Notification Plugin's MessagingService class along with FirebaseMessagingService.

package com.example.application

import android.annotation.SuppressLint
import android.content.Intent
import androidx.core.content.ContextCompat
import breez_sdk_notification.Constants
import breez_sdk_notification.Message
import breez_sdk_notification.MessagingService

class ExampleFcmService : MessagingService, FirebaseMessagingService() {
    companion object {
        private const val TAG = "FcmService"

    // Override the `onMessageReceived` to handle the remote message
    override fun onMessageReceived(remoteMessage: RemoteMessage) {

        // Check if the message is high priority and can be handled
        if (remoteMessage.priority == RemoteMessage.PRIORITY_HIGH) {
            remoteMessage.asMessage()?.also { message -> 
                // Call `startServiceIfNeeded` to check if the foreground
                // service is needed depending on the message type and 
                // foreground state of the application
                startServiceIfNeeded(applicationContext, message)

    // A helper function the convert the `RemoteMessage` 
    // to a notification plugin 'Message'
    private fun RemoteMessage.asMessage(): Message? {
        return data[Constants.MESSAGE_DATA_TYPE]?.let {
                data[Constants.MESSAGE_DATA_TYPE], data[Constants.MESSAGE_DATA_PAYLOAD]

    // Override the `startForegroundService` function to start the foreground service
    // using the `ExampleForegroundService` handler
    override fun startForegroundService(message: Message) {
        val intent = Intent(applicationContext,
        intent.putExtra(Constants.EXTRA_REMOTE_MESSAGE, message)
        ContextCompat.startForegroundService(applicationContext, intent)

Now lets add the foreground service implementation. This should implement the notification plugin ForegroundService class, which handles the incoming notification intent and processes the event. To properly implement this, your class needs to override the onCreate, getConnectRequest and getServiceConfig functions. The getConnectRequest function is called by the ForegroundService to get a BreezSDK ConnectRequest which contains the data necessary to connect the SDK to the node. This data includes the Breez API key, the Config with it's workingDir and the node seed.

Developer note

In Android reading from secured storage can vary a lot depending if it is a Kotlin, Flutter or React Native based application and the dependencies used to write to the secured storage. Consult the dependency used to write to the secured storage on how to read data back from them.
package com.example.application

import breez_sdk.ConnectRequest
import breez_sdk.EnvironmentType
import breez_sdk.GreenlightNodeConfig
import breez_sdk.NodeConfig
import breez_sdk.defaultConfig
import breez_sdk.mnemonicToSeed
import breez_sdk_notification.ForegroundService
import breez_sdk_notification.NotificationHelper.Companion.registerNotificationChannels
import breez_sdk_notification.ServiceConfig
import com.example.application.BuildConfig

class ExampleForegroundService : ForegroundService() {
    companion object {
        private const val TAG = "ForegroundService"
        private const val ACCOUNT_MNEMONIC = "BREEZ_SDK_SEED_MNEMONIC"

    // Override the `onCreate` function
    override fun onCreate() {
        // Register the default notification channels

    // Override the `getConnectRequest` function
    override fun getConnectRequest(): ConnectRequest? {
        // Get the Breez API key from the build config
        val apiKey = BuildConfig.BREEZ_SDK_API_KEY
        val glNodeConf = GreenlightNodeConfig(null, null)
        val nodeConf = NodeConfig.Greenlight(glNodeConf)
        val config = defaultConfig(EnvironmentType.PRODUCTION, apiKey, nodeConf)

        // Set the workingDir as the same directory as the main application
        config.workingDir = "${applicationContext.filesDir}/breezSdk"

        // Get the mnemonic from secured storage using an implementation of
        // `readSecuredValue` depending on how data is written to secured storage.
        // See Developer Note
        return readSecuredValue(applicationContext, ACCOUNT_MNEMONIC)
            ?.let { mnemonic ->
                ConnectRequest(config, mnemonicToSeed(mnemonic))

    // Override the `getServiceConfig` function
    override fun getServiceConfig(): ServiceConfig? {
        // For now just return the default config
        return ServiceConfig.default()

Reference implementation

For a complete reference, see how we implemented it in c-breez wallet: BreezFcmService.kt.