PluginRegistry cannot be converted to FlutterEngine

FirebaseFlutterFirebase Cloud-MessagingFlutter Dependencies

Firebase Problem Overview


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);
  }
}

Firebase Solutions


Solution 1 - Firebase

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;

Solution 2 - Firebase

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

Solution 3 - Firebase

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
    }
  }
}

Solution 4 - Firebase

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"));
  }
}

Solution 5 - Firebase

Just Do

GeneratedPluginRegistrant.registerWith((FlutterEngine) registry);

inplace of

GeneratedPluginRegistrant.registerWith(registry);

Solution 6 - Firebase

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.

Solution 7 - Firebase

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;
}}

Solution 8 - Firebase

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGabriel G. PavanView Question on Stackoverflow
Solution 1 - Firebasemehrdad seyrafiView Answer on Stackoverflow
Solution 2 - FirebaseDomingoMGView Answer on Stackoverflow
Solution 3 - FirebaseVinicius ZaniView Answer on Stackoverflow
Solution 4 - FirebaseYuvraj SinghView Answer on Stackoverflow
Solution 5 - FirebaseSrijanView Answer on Stackoverflow
Solution 6 - FirebaseAxes GrindsView Answer on Stackoverflow
Solution 7 - Firebasesevki.ctnrView Answer on Stackoverflow
Solution 8 - FirebaseTal A. JacobsonView Answer on Stackoverflow