Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

[firebase_messaging] Handle background messages in a kotlin project #2177

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
royibernthal opened this issue Mar 16, 2020 · 4 comments
Closed
Labels
Stale Issue with no recent activity type: documentation Improvements or additions to documentation type: enhancement New feature or request

Comments

@royibernthal
Copy link

royibernthal commented Mar 16, 2020

It seems there's no official documentation on handling background messages in a kotlin based project.

Please write documentation for it, there's a lot of confusion around this.

I tried to search similar issues and stumbled upon:
#111

As suggested in that issue, I added the following Application.kt:

package com.mycomapny.myapp

import android.os.Bundle

import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService

class Application : FlutterApplication() , PluginRegistrantCallback {

    override fun onCreate() {
        super.onCreate();

        FlutterFirebaseMessagingService.setPluginRegistrant(this);
    }

    override fun registerWith(registry: PluginRegistry) {
        GeneratedPluginRegistrant.registerWith(registry);
    }
    
}

I removed configureFlutterEngine from MainActivity.kt (well, until this is solved it's just commented out):

package com.mycompany.myapp

import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity: FlutterActivity() {
    /*override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);
    }*/
}

I modified android:name in AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mycompany.myapp">
    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->
    <application
        android:name=".Application"
        android:label="My App Label"
        android:icon="@mipmap/launcher_icon">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <intent-filter>
                <action android:name="FLUTTER_NOTIFICATION_CLICK" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

I added com.google.firebase:firebase-messaging to app/build.gradle:

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'io.fabric'
apply plugin: 'com.google.gms.google-services'

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

android {
    compileSdkVersion 28

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    lintOptions {
        disable 'InvalidPackage'
    }

    defaultConfig {
        applicationId "com.mycompany.myapp"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
            storePassword keystoreProperties['storePassword']
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

flutter {
    source '../..'
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.google.firebase:firebase-messaging:20.1.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

When trying to build, I got the following error:

e: D:\Projects\mycompany\myapp\android\app\src\main\kotlin\com\mycompany\myapp\Application.kt: (20, 48): Type mismatch: inferred type is PluginRegistry but FlutterEngine was expected

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:compileDebugKotlin'.
> Compilation error. See log for more details

I then stumbled upon:
https://stackoverflow.com/a/60531819/5882529

After following it I was finally able to build, but I'm not able to intercept any background message.
I'm testing on Android Emulator: Pixel 3a, Android Q.

That's what I get when I run flutter doctor -v:

[√] Flutter (Channel stable, v1.12.13+hotfix.8, on Microsoft Windows [Version 10.0.18362.720], locale en-US)
    • Flutter version 1.12.13+hotfix.8 at D:\flutter
    • Framework revision 0b8abb4724 (5 weeks ago), 2020-02-11 11:44:36 -0800
    • Engine revision e1e6ced81d
    • Dart version 2.7.0


[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at C:\Users\royib\AppData\Local\Android\Sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.3
    • ANDROID_HOME = C:\Users\royib\AppData\Local\Android\Sdk
    • Java binary at: D:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)
    • All Android licenses accepted.

[√] Android Studio (version 3.6)
    • Android Studio at D:\Program Files\Android\Android Studio
    • Flutter plugin version 44.0.2
    • Dart plugin version 192.7761
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)

[!] IntelliJ IDEA Community Edition (version 2018.1)
    • IntelliJ at D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.1
    X Flutter plugin not installed; this adds Flutter specific functionality.
    X Dart plugin not installed; this adds Dart specific functionality.
    • For information about installing plugins, see
      https://flutter.dev/intellij-setup/#installing-the-plugins

[!] Connected device
    ! No devices available

I have IntelliJ IDEA Community Edition installed separately from Android Studio but I'm using Android Studio which does have the Flutter and Dart plugins installed, so that warning can be ignored.

@royibernthal royibernthal added the type: bug Something isn't working label Mar 16, 2020
@hw-dwalter
Copy link

Here https://github.com/hw-dwalter/flutter-firebase-messaging-background-example you can find my sample project with working background messages in kotlin. everything is fine except of this behaviour https://youtu.be/frhnHX8Z-UQ

@iapicca iapicca added type: documentation Improvements or additions to documentation type: enhancement New feature or request and removed type: bug Something isn't working labels Mar 20, 2020
@consoldev
Copy link

Any idea how to integrate MethodChannels in this scenario?

@brokenalarms
Copy link

brokenalarms commented Apr 5, 2020

+1 to this, I had no idea that the android portion of my Flutter project was in Kotlin rather than Java until I got to the 'create MainActivity.java' instruction and got stuck. So the instructions are currently unclear.

Have followed the guides above (thanks so much for writing!) and can now send messages but not background messages.

@helenaford helenaford changed the title Handle background messages in a kotlin project [firebase_messaging] Handle background messages in a kotlin project Apr 20, 2020
@johnMinelli
Copy link

Is this right?
`

    <!-- Don't delete the meta-data below.
         This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
    <meta-data
        android:name="flutterEmbedding"
        android:value="2" />
</application>`

The guide says :

6 Add a new <meta-data> tag under <application>.

@Salakar Salakar added the Stale Issue with no recent activity label Apr 1, 2021
@Salakar Salakar closed this as completed Apr 1, 2021
@firebase firebase locked and limited conversation to collaborators Apr 1, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Stale Issue with no recent activity type: documentation Improvements or additions to documentation type: enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

7 participants