PluginRegistry cannot be converted to FlutterEngine

As soon as I updated the flutter to version 1.12.13 I found this issue and can't fix it. I did as the firebase_messaging tutorial sent and got the following error: "error: incompatible types: PluginRegistry cannot be converted to FlutterEngine GeneratedPluginRegistrant.registerWith (registry); " My code is as follows:

package io.flutter.plugins;


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;


import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;


public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
FlutterFirebaseMessagingService.setPluginRegistrant(this);


if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
NotificationChannel channel = new NotificationChannel("messages","Messages", NotificationManager.IMPORTANCE_LOW);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}
}


@Override
public void registerWith(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}
37066 次浏览

Updated on December 31, 2019.

You should not use the Firebase cloud messaging tool to send notifications, as it forces you to use the title and body.

You must send a notification without the title and body. have the application in the background, that should work for you.

If it works for you, I would appreciate it if you could give me a vote on this answer, thank you.


I have found a temporary solution. I am not sure this is the best fix but my plugins work as expected and I assume the problem has to be with the registry provided by io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService on line 164.

My AndroidManifest.xml file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="Your Package"> // CHANGE THIS


<application
android:name=".Application"
android:label="" // YOUR NAME APP
android:icon="@mipmap/ic_launcher">
<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>
<!-- BEGIN: Firebase Cloud Messaging -->
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<!-- END: Firebase Cloud Messaging -->
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>

My Application.java

package YOUR PACKAGE HERE;


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


public class Application extends FlutterApplication implements PluginRegistrantCallback {


@Override
public void onCreate() {
super.onCreate();
FlutterFirebaseMessagingService.setPluginRegistrant(this);
}


@Override
public void registerWith(PluginRegistry registry) {
FirebaseCloudMessagingPluginRegistrant.registerWith(registry);
}
}

My FirebaseCloudMessagingPluginRegistrant.java

package YOUR PACKAGE HERE;


import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;


public final class FirebaseCloudMessagingPluginRegistrant{
public static void registerWith(PluginRegistry registry) {
if (alreadyRegisteredWith(registry)) {
return;
}
FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
}


private static boolean alreadyRegisteredWith(PluginRegistry registry) {
final String key = FirebaseCloudMessagingPluginRegistrant.class.getCanonicalName();
if (registry.hasPlugin(key)) {
return true;
}
registry.registrarFor(key);
return false;
}
}

Send Notification in dart:

Future<void> sendNotificationOnBackground({
@required String token,
}) async {
await firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(sound: true, badge: true, alert: true, provisional: false),
);
await Future.delayed(Duration(seconds: 5), () async {
await http.post(
'https://fcm.googleapis.com/fcm/send',
headers: <String, String>{
'Content-Type': 'application/json',
'Authorization': 'key=$SERVERTOKEN', // Constant string
},
body: jsonEncode(
<String, dynamic>{
'notification': <String, dynamic>{


},
'priority': 'high',
'data': <String, dynamic>{
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
'id': '1',
'status': 'done',
'title': 'title from data',
'message': 'message from data'
},
'to': token
},
),
);
});
}

I added a wait with a duration of 5 seconds so you can put the application in the background and verify that the message in the background is running

In addition to DomingoMG's answer, don't forget to remove

@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);

from the mainactivity file under the android folder. If not, you will get an error.

A port of DomingoMG's code to Kotlin can be found below (file paths included). Tested and working on 10.2020.

/pubspec.yaml

firebase_messaging: ^7.0.0

/android/app/src/main/kotlin/Application.kt

package YOUR_PACKAGE_HERE


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


public class Application: FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this)
}


override fun registerWith(registry: PluginRegistry) {
FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
}
}

/android/app/src/main/kotlin/FirebaseCloudMessagingPluginRegistrant.kt

package YOUR_PACKAGE_HERE


import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin


class FirebaseCloudMessagingPluginRegistrant {
companion object {
fun registerWith(registry: PluginRegistry) {
if (alreadyRegisteredWith(registry)) {
return;
}
FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"))
}


fun alreadyRegisteredWith(registry: PluginRegistry): Boolean {
val key = FirebaseCloudMessagingPluginRegistrant::class.java.name
if (registry.hasPlugin(key)) {
return true
}
registry.registrarFor(key)
return false
}
}
}

I added only water class as extra from the steps in Firebase Messaging package and it was solved :

import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
public final class FirebaseCloudMessagingPluginRegistrant{
public static void registerWith(PluginRegistry registry) {
if (alreadyRegisteredWith(registry)) {
return;
}
FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
}


private static boolean alreadyRegisteredWith(PluginRegistry registry) {
final String key = FirebaseCloudMessagingPluginRegistrant.class.getCanonicalName();
if (registry.hasPlugin(key)) {
return true;
}
registry.registrarFor(key);
return false;
}}

Replace this code line:

GeneratedPluginRegistrant.registerWith(registry);

with this:

FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));

Make sure to import:

import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;

I found this to work:

@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
// continue with custom method channel registration.
...
}

Not sure if you also need to use cleanUpFlutterEngine to clean method channel registration.

Just Do

GeneratedPluginRegistrant.registerWith((FlutterEngine) registry);

inplace of

GeneratedPluginRegistrant.registerWith(registry);

Some research and I found this to be working.
Seached up the official Flutterfire repository, and checked out the latest plugins on it. GeneratedPluginRegistrant.registerWith(registry); was not working, which is mentioned on the official docs as well. FlutterFire firebase_messaging.

Using the plugin io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingPlugin, which I discovered from Flutterfire GitHub repo

Currently on firabase_messaging: 9.0.0

//
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingBackgroundService;
// Be sure to import the exact Plugin
import io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingPlugin;


public class Application extends FlutterApplication implements PluginRegistrantCallback {
//
@Override
public void onCreate() {
super.onCreate();
FlutterFirebaseMessagingBackgroundService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
FlutterFirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
}
}

Change your MainActivity.java file to: package co.appbrewery.micard;

import io.flutter.embedding.android.FlutterActivity;

public class MainActivity extends FlutterActivity {

}