PluginRegistry no se puede convertir a FlutterEngine

22

Tan pronto como actualicé el flutter a la versión 1.12.13, encontré este problema y no puedo solucionarlo. Hice lo que envió el tutorial firebase_messaging y recibí el siguiente error: "error: tipos incompatibles: PluginRegistry no se puede convertir a FlutterEngine GeneratedPluginRegistrant.registerWith (registro);" Mi código es el siguiente:

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);
  }
}
Gabriel G. Pavan
fuente
Estoy recibiendo este error también. alguna solución todavía?
ajonno
No. Lo intenté y no pude
Gabriel G. Pavan

Respuestas:

21

Actualizado el 31 de diciembre de 2019.

No debes usar la herramienta de mensajería en la nube Firebase para enviar notificaciones, ya que te obliga a usar el título y el cuerpo.

Debe enviar una notificación sin el título y el cuerpo. tener la aplicación en segundo plano, eso debería funcionar para usted.

Si te funciona, te agradecería que me dieras un voto sobre esta respuesta, gracias.


He encontrado una solución temporal. No estoy seguro de que esta sea la mejor solución, pero mis complementos funcionan como se esperaba y supongo que el problema tiene que ver con el registro proporcionado por io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService en la línea 164.

Mi archivo AndroidManifest.xml:

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

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

Enviar notificación en dardo:

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

Agregué una espera con una duración de 5 segundos para que pueda poner la aplicación en segundo plano y verificar que el mensaje en segundo plano se esté ejecutando

DomingoMG
fuente
Lo intenté es su solución, pero no tuve éxito, en los estados ONLAUNCH, ONRESUME y ONMESSAGE aparecieron, solo en ONBACKGROUND no. Puse el archivo FirebaseCloudMessagingPluginRegistrant.java en la misma carpeta que Application.java, ¿verdad? Espero que el equipo de Flutter resuelva este problema pronto. Para entonces tendré que usar la versión 1.9.1, aunque tengo tantas ganas de usar 1.12.13
Gabriel G. Pavan
¿Podría crear un proyecto y darme el enlace en su github para que lo descargue e intente ejecutarlo en mi proyecto de prueba de Firebase?
Gabriel G. Pavan
He actualizado la respuesta, me perdí un hecho importante para agregar.
DomingoMG
Dejo una estructura que me ha ayudado a enviar notificaciones push con dardo
DomingoMG
Esto funcionó. No estoy seguro de por qué, pero lo hizo. Espero que el equipo flutter arregle esto en el próximo lanzamiento
Avi
10

Un puerto del código de DomingoMG a Kotlin se puede encontrar a continuación. Probado y funcionando en marzo de 2020.

pubspec.yaml

firebase_messaging: ^6.0.12

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

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
    }
  }
}
Vinicius Zani
fuente
Hola, `` Error de ejecución para la tarea ': aplicación: mergeDexDebug'. > Se produjo un error al ejecutar com.android.build.gradle.internal.tasks.Workers $ ActionFacade> com.android.builder.dexing.DexArchiveMergerException: Error al fusionar archivos dex: aprenda a resolver el problema en developer.android.com / studio / build /… . Tipo de programa ya presente: com.example.gf_demo.FirebaseCloudMessagingPluginRegistrant ``
Kamil
7

Reemplace su línea de código a continuación:

GeneratedPluginRegistrant.registerWith(registry);

con este:

FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
mehrdad seyrafi
fuente
1
Funcionó ... solo recuerda importar la clase mencionada. import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
zion
1

Además de la respuesta de DomingoMG, no olvides eliminar

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

desde el archivo de mainactividad en la carpeta de Android. Si no, obtendrá un error.

Rectificado de ejes
fuente
¿Pero dónde puedo registrar mi propio MethodChannel, cuando elimine configureFlutterEngine?
Kamil Svoboda
Según la respuesta de DomingoMG, FirebaseCloudMessagingPluginRegistrant.java ya realiza el registro de "registerWith ...", por eso ya no es necesario configureFlutterEngine. Eso responde tu pregunta?
Ejes Grinds
Entiendo que FirebaseCloudMessagingPluginRegistrant.java realiza el registro en lugar de configureFlutterEngine. Pero configureFlutterEngine es el lugar donde puedo registrar mi propio MethodChannel para llamar a la API nativa (consulte "Escritura de código personalizado de plataforma específica" en flutter.dev). ¿Dónde puedo registrar MethodChannel cuando se elimina el método configureFlutterEngine?
Kamil Svoboda
No tengo ninguna experiencia con la escritura de código específico de la plataforma. Lo siento, no puedo ayudar con esa información. Espero que hayas encontrado una respuesta.
Ejes muele el
1

Agregué solo la clase de agua como extra de los pasos en el paquete de Firebase Messaging y se resolvió:

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