PluginRegistry cannot be converted to FlutterEngine

Solution 1:

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:

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:

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