Describe the bug
At https://pub.dev/packages/firebase_messaging step 6 of backgrond messaging talks about MainActivity.java but it does not exist for my Flutter project.

Looks like a lot of others have this issue https://stackoverflow.com/questions/59225943/flutter-project-mainactivity-java-is-missing
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Additional context
Add any other context about the problem here.
Hi @giorgio79
Your project has Kotlin instead of Java . You can implement MainActivity.kt from this answer
or you can create Flutter project with java support an follow the steps to implement firebase_messaging
Closing, as this isn't an issue with firebase_messaging itself,
if you disagree please write in the comments and I will reopen it
Thank you
Thanks Taha. Perhaps the documentaiton could be improved at https://pub.dev/packages/firebase_messaging
I assume the kotlin based projects will prevail over pure Java, as Flutter rocks.
Hi @giorgio79
Yes, it should be updated
Just found a dupe thread :) https://github.com/FirebaseExtended/flutterfire/issues/1906
PS, it is also unclear whether we should paste the stuff after what is in MainActivity.kt or overwrite what is in there? For now, I just pasted after what was in there...
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
//https://stackoverflow.com/questions/59984162/firebase-messaging-handle-background-message-in-kotlin/60634673#60634673
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
class Application : FlutterApplication(), PluginRegistrantCallback {
fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this)
}
fun registerWith(registry: PluginRegistry?) {
GeneratedPluginRegistrant.registerWith(registry)
}
}
Ok, I think the Google team needs to do a better job. I am unsuccessful so far in updating my main Kotlin file, getting errors like this based on the linked stackoverflow kotlin example... The imports are also totally different from the default kotlin file provided out of the box...
package me.exampleapp
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
//https://stackoverflow.com/questions/59984162/firebase-messaging-handle-background-message-in-kotlin/60634673#60634673
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
class Application : FlutterApplication(), PluginRegistrantCallback {
fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this)
}
fun registerWith(registry: PluginRegistry?) {
GeneratedPluginRegistrant.registerWith(registry)
}
}
Launching lib\main.dart on Pixel 2 in debug mode...
Running Gradle task 'assembleDebug'...
C:\AndroidStudioProjects\exampleapp\android\app\src\main\kotlin\me\exampleapp\MainActivity.kt: (15, 9): 'onCreate' hides member of supertype 'FlutterApplication' and needs 'override' modifier
C:\AndroidStudioProjects\exampleapp\android\app\src\main\kotlin\me\exampleapp\MainActivity.kt: (20, 9): 'registerWith' hides member of supertype 'PluginRegistrantCallback' and needs 'override' modifier
C:\AndroidStudioProjects\exampleapp\android\app\src\main\kotlin\me\exampleapp\MainActivity.kt: (21, 48): Type mismatch: inferred type is PluginRegistry? but FlutterEngine was expected
FAILURE: Build failed with an exception.
Lol I am finding so many issues around this and the plugin page has no up to date documentation ... WTF Simple carelessness...
https://github.com/FirebaseExtended/flutterfire/issues/1684
https://github.com/FirebaseExtended/flutterfire/issues/1613
Thanks Taha! Looking forward to a working Kotlin / Flutter example. The example linked from firebase_messaging pub dart page is 3 years old and Java based... https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_messaging/example
Update: based in another plugin that I'm using in another app, I'm ussing this code for handle background message in kotlin... I don't know is better than stackoverflow answer, but works.
Application.kt
package your.app.package
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin
import io.flutter.view.FlutterMain
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this);
FlutterMain.startInitialization(this)
}
override fun registerWith(registry: PluginRegistry?) {
if (!registry!!.hasPlugin("io.flutter.plugins.firebasemessaging")) {
FirebaseMessagingPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
}
}
}
Update: based in another plugin that I'm using in another app, I'm ussing this code for handle background message in kotlin... I don't know is better than stackoverflow answer, but works.
Application.kt
package your.app.package import io.flutter.app.FlutterApplication import io.flutter.plugin.common.PluginRegistry import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin import io.flutter.view.FlutterMain import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService class Application : FlutterApplication(), PluginRegistrantCallback { override fun onCreate() { super.onCreate() FlutterFirebaseMessagingService.setPluginRegistrant(this); FlutterMain.startInitialization(this) } override fun registerWith(registry: PluginRegistry?) { if (!registry!!.hasPlugin("io.flutter.plugins.firebasemessaging")) { FirebaseMessagingPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")); } } }
Yes, It works! Thank You
Update: based in another plugin that I'm using in another app, I'm ussing this code for handle background message in kotlin... I don't know is better than stackoverflow answer, but works.
Application.kt
package your.app.package import io.flutter.app.FlutterApplication import io.flutter.plugin.common.PluginRegistry import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin import io.flutter.view.FlutterMain import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService class Application : FlutterApplication(), PluginRegistrantCallback { override fun onCreate() { super.onCreate() FlutterFirebaseMessagingService.setPluginRegistrant(this); FlutterMain.startInitialization(this) } override fun registerWith(registry: PluginRegistry?) { if (!registry!!.hasPlugin("io.flutter.plugins.firebasemessaging")) { FirebaseMessagingPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")); } } }
Can you share everything you've done?
Did you remove your MainActivity file? Did you update your AndroidManifest.xml android:name?
You have to update the AndroidManifest.xml as well.
- android:name="io.flutter.app.FlutterApplication"
+ android:name=".Application"
and add:
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
inside the <activity tag.
You have to update the
AndroidManifest.xmlas well.- android:name="io.flutter.app.FlutterApplication" + android:name=".Application"and add:
<intent-filter> <action android:name="FLUTTER_NOTIFICATION_CLICK" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>inside the
<activitytag.
Is there more of your implementation you can share? Like a spoonfeeding of information?
How did you declare your myBackgroundMessageHandler function?
What are you using for MainActivity.kt?
What are you using for Application.kt?
What does your AndroidManifest have in it?
Does the package name at the top match what's in google-services.json? Does it match what's in the MainActivity.kt?
What version of the actual plugin are yo using in pubspec?
What version of the android/app/build.gradle dependency are you using?
Ex: implementation "com.google.firebase:firebase-messaging:XXXX
My mind is blown by this plugin. None of it makes sense, thanks in advance.
@bretie you need to follow the pub.dev documentation https://pub.dev/packages/firebase_messaging
The only thing that change from that for flutter kotlin projects is the code below the step that says:
_2. Add an Application.java class to your app in the same directory as your MainActivity.java. This is typically found in
If the proccess is too complicated you can search for a youtube video
@bretie you need to follow the pub.dev documentation https://pub.dev/packages/firebase_messaging
The only thing that change from that for flutter kotlin projects is the code below the step that says:
_2. Add an Application.java class to your app in the same directory as your MainActivity.java. This is typically found in /android/app/src/main/java//._
If the proccess is too complicated you can search for a youtube video
I can assure you it's not too complicated. When it comes to background messages using this plug it tends to be inconsistent compatibility. It requires unique steps for every other person that aren't documented. Hence, me asking for your full implementation.
Update: based in another plugin that I'm using in another app, I'm ussing this code for handle background message in kotlin... I don't know is better than stackoverflow answer, but works.
Application.kt
package your.app.package import io.flutter.app.FlutterApplication import io.flutter.plugin.common.PluginRegistry import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin import io.flutter.view.FlutterMain import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService class Application : FlutterApplication(), PluginRegistrantCallback { override fun onCreate() { super.onCreate() FlutterFirebaseMessagingService.setPluginRegistrant(this); FlutterMain.startInitialization(this) } override fun registerWith(registry: PluginRegistry?) { if (!registry!!.hasPlugin("io.flutter.plugins.firebasemessaging")) { FirebaseMessagingPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")); } } }
I' ve spend around 2 hours to find fix for this. Thanks a lot. You saved me.
@giorgio79 Did you find a solution yet for this ?
Update: based in another plugin that I'm using in another app, I'm ussing this code for handle background message in kotlin... I don't know is better than stackoverflow answer, but works.
Application.ktpackage your.app.package import io.flutter.app.FlutterApplication import io.flutter.plugin.common.PluginRegistry import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin import io.flutter.view.FlutterMain import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService class Application : FlutterApplication(), PluginRegistrantCallback { override fun onCreate() { super.onCreate() FlutterFirebaseMessagingService.setPluginRegistrant(this); FlutterMain.startInitialization(this) } override fun registerWith(registry: PluginRegistry?) { if (!registry!!.hasPlugin("io.flutter.plugins.firebasemessaging")) { FirebaseMessagingPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")); } } }I' ve spend around 2 hours to find fix for this. Thanks a lot. You saved me.
Buddy, you saved my day.
@giorgio79 , I struggled with this for many hours. Even the above solutions didn't work for me. Finally found a way solve this. Here is how I managed to fix this.
AndroidManifest.xml name properties as below.<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<application
android:name=".Application">
<activity
android:name=".MainActivity">
</activity>
</application>
</manifest>
MainActivity.kt file as below.package com.example.app
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() {}
FirebaseCloudMessagingPluginRegistrant.kt file in same directory.package com.example.app
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin
object FirebaseCloudMessagingPluginRegistrant {
fun registerWith(registry: PluginRegistry?) {
if (alreadyRegisteredWith(registry)) {
return
}
FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"))
}
private fun alreadyRegisteredWith(registry: PluginRegistry?): Boolean {
val key: String? = FirebaseCloudMessagingPluginRegistrant::class.java.canonicalName
if (registry?.hasPlugin(key)!!) {
return true
}
registry.registrarFor(key)
return false
}
}
Application.kt file in same directory.package com.example.app
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this)
}
override fun registerWith(registry: PluginRegistry?) {
FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
}
}
You have to update the
AndroidManifest.xmlas well.- android:name="io.flutter.app.FlutterApplication" + android:name=".Application"and add:
<intent-filter> <action android:name="FLUTTER_NOTIFICATION_CLICK" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>inside the
<activitytag.
thanks a lot @hectorAguero and @hpadrao ,
i misstype changing android:name --> .Application inside activity instead of android:name inside application tag.
Totally lost with Kotlin implementation. This issue has been open for 5 months. We need an immediate solution.
@giorgio79 , I struggled with this for many hours. Even the above solutions didn't work for me. Finally found a way solve this. Here is how I managed to fix this.
- Change
AndroidManifest.xmlname properties as below.<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.app"> <application android:name=".Application"> <activity android:name=".MainActivity"> </activity> </application> </manifest>
- Empty
MainActivity.ktfile as below.package com.example.app import androidx.annotation.NonNull; import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugins.GeneratedPluginRegistrant class MainActivity: FlutterActivity() {}
- Add
FirebaseCloudMessagingPluginRegistrant.ktfile in same directory.package com.example.app import io.flutter.plugin.common.PluginRegistry import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin object FirebaseCloudMessagingPluginRegistrant { fun registerWith(registry: PluginRegistry?) { if (alreadyRegisteredWith(registry)) { return } FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")) } private fun alreadyRegisteredWith(registry: PluginRegistry?): Boolean { val key: String? = FirebaseCloudMessagingPluginRegistrant::class.java.canonicalName if (registry?.hasPlugin(key)!!) { return true } registry.registrarFor(key) return false } }
- Add
Application.ktfile in same directory.package com.example.app import io.flutter.app.FlutterApplication import io.flutter.plugin.common.PluginRegistry import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService class Application : FlutterApplication(), PluginRegistrantCallback { override fun onCreate() { super.onCreate() FlutterFirebaseMessagingService.setPluginRegistrant(this) } override fun registerWith(registry: PluginRegistry?) { FirebaseCloudMessagingPluginRegistrant.registerWith(registry) } }
Esta es la solucion al problema. A mi me funcion perfectamente. No me habia dado cuenta que no tenia los archivos en un mismo directorio. Espero que esto le sirva a otras personas.
This took me a while to figure out but here is a working solution:
You'll need two files in the SAME directory as your MainActivity.kt. The two files:
MainActivity.kt
This file will stay the same.
package com.example.app
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}
Application.kt
package com.example.app
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin
import io.flutter.view.FlutterMain
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this);
FlutterMain.startInitialization(this)
}
override fun registerWith(registry: PluginRegistry?) {
if (!registry!!.hasPlugin("io.flutter.plugins.firebasemessaging")) {
FirebaseMessagingPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
}
}
}
You then need to update your AndroidManifest.xml to point at these two files. You do this like this:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<!-- 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="io.flutter.app.FlutterApplication"
-->
<application
android:name=".Application"
android:label="example"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
So, you've essentially replaced the application file and kept the main activity the same.
Don't forget
You need to drop this in the AndroidManifest.xml file as well within the activity tags.
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
No Application.kt any more.
I follow this doc and it works fine.
https://firebase.flutter.dev/docs/messaging/overview
firebase_core: ^0.5.1
firebase_messaging: ^8.0.0-dev.5
ps. I am using Flutter Android Embedding V2
Hope this helps.
I also moved my app from Kotlin to Java. Kotlin first development is a lie and we shouldn't rely on fancy announcements.
Deprecated doc killing many apps including mine. There r many solutions but I don't know which one should be final. Plz consider to update the doc
didnt read a lot of these posts, but i managed to get push working on an emulator, running a flutter build.
the main thing u gotta use is PlatformChannel, to call a method written in kt/java files from the flutter widget or flutter file.
u gotta setup the channel on both sides of the code, so flutter calls method using PlatformChannel and kotlin/java recieves the call.
i succesfully got a push message from the console on a flutter app.
the instructions provided online are OK but somewhat confusing with all the classes (somewhat bulky) u gotta use, especially if ure not experienced.
i have found the solution for this problem
first you have to create 2 files in the same directory of MainActivity.kt:
1- Application.kt:
` package import io.flutter.app.FlutterApplication class Application : FlutterApplication(), PluginRegistrantCallback { } ` `` import io.flutter.plugin.common.PluginRegistry object FirebaseCloudMessagingPluginRegistrant { }` 3- then modify MainActivity.kt to look like: import androidx.annotation.NonNull class MainActivity: FlutterActivity() { 4- reference MainActivity.kt and Application.kt in Androidmainfest.xml file:
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingServiceoverride fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this);
}
override fun registerWith(registry: PluginRegistry?) {
io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
}
2- create FirebaseCloudMessagingPluginRegistrant.kt:
package
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin
fun registerWith(registry: PluginRegistry?) {
if (alreadyRegisteredWith(registry)) {
return
}
FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"))
}private fun alreadyRegisteredWith(registry: PluginRegistry?): Boolean {
val key: String? = FirebaseCloudMessagingPluginRegistrant::class.java.canonicalName
if (registry?.hasPlugin(key)!!) {
return true
}
registry.registrarFor(key)
return false
}
`package
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}
`
a- <application
android:name="com.blablabla.Application"
b-<activity android:name="com.blablabla.MainActivity"
Most helpful comment
Update: based in another plugin that I'm using in another app, I'm ussing this code for handle background message in kotlin... I don't know is better than stackoverflow answer, but works.
Application.kt