O PluginRegistry não pode ser convertido em FlutterEngine

22

Assim que atualizei o flutter para a versão 1.12.13, encontrei esse problema e não consigo corrigi-lo. Fiz como o tutorial firebase_messaging enviado e recebi o seguinte erro: "erro: tipos incompatíveis: PluginRegistry não pode ser convertido em FlutterEngine GeneratedPluginRegistrant.registerWith (registry);" Meu código é o seguinte:

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
fonte
Estou recebendo esse erro também. alguma solução ainda?
ajonno
Não. Eu tentei e não podia
Gabriel G. Pavan

Respostas:

21

Atualizado em 31 de dezembro de 2019.

Você não deve usar a ferramenta de mensagens em nuvem do Firebase para enviar notificações, pois ela o força a usar o título e o corpo.

Você deve enviar uma notificação sem o título e o corpo. tenha o aplicativo em segundo plano, que deve funcionar para você.

Se funcionar para você, eu apreciaria se você pudesse me votar nesta resposta, obrigado.


Eu encontrei uma solução temporária. Não sei se essa é a melhor correção, mas meus plug-ins funcionam como esperado e presumo que o problema esteja no registro fornecido por io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService na linha 164.

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

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

Enviar notificação no 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
     },
    ),
  );
  });  
}

Adicionei uma espera com duração de 5 segundos para que você possa colocar o aplicativo em segundo plano e verificar se a mensagem em segundo plano está sendo executada

DomingoMG
fonte
Eu tentei é a sua solução, mas não tive êxito, nos estados ONLAUNCH, ONRESUME e ONMESSAGE apareceram, apenas no ONBACKGROUND, não. Coloquei o arquivo FirebaseCloudMessagingPluginRegistrant.java na mesma pasta que Application.java, estava certo? Espero que a equipe do Flutter resolva esse problema em breve. Até lá terei que usar a versão 1.9.1, embora eu queira tanto usar a 1.12.13
Gabriel G. Pavan
Você poderia criar um projeto e fornecer o link no seu github para fazer o download e tentar executá-lo no meu projeto de teste do Firebase?
Gabriel G. Pavan
Atualizei a resposta, perdi um fato importante a acrescentar.
DomingoMG
Deixo uma estrutura que me ajudou a enviar notificações push com dardo
DomingoMG
Isso funcionou. Não sei por que, mas fez. Espero que a equipe de vibração conserte isso no próximo lançamento
Avi
10

Uma porta do código do DomingoMG para Kotlin pode ser encontrada abaixo. Testado e funcionando em março 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
fonte
Olá, `` `Falha na execução da tarefa ': app: mergeDexDebug'. > Ocorreu uma falha ao executar com.android.build.gradle.internal.tasks.Workers $ ActionFacade> com.android.builder.dexing.DexArchiveMergerException: erro ao mesclar arquivos dex: saiba como resolver o problema em developer.android.com / estúdio / compilação /… . Tipo de programa já presente: com.example.gf_demo.FirebaseCloudMessagingPluginRegistrant `` `
Kamil
7

Substitua sua linha de código abaixo:

GeneratedPluginRegistrant.registerWith(registry);

com isso:

FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
mehrdad seyrafi
fonte
11
Funcionou ... lembre-se de importar a classe mencionada. import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
zion
1

Além da resposta do DomingoMG, não se esqueça de remover

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

do arquivo de atividade na pasta android. Caso contrário, você receberá um erro.

Moinhos de eixos
fonte
Mas onde posso registrar meu próprio MethodChannel, quando removerei o configureFlutterEngine?
Kamil Svoboda
De acordo com a resposta do DomingoMG, o FirebaseCloudMessagingPluginRegistrant.java já faz o registro de "registerWith ..." e é por isso que o configureFlutterEngine não é mais necessário. Isso responde à sua pergunta?
Axes Grinds
Entendo que o FirebaseCloudMessagingPluginRegistrant.java faz o registro em vez de configureFlutterEngine. Mas configureFlutterEngine é um local onde eu posso registrar meu próprio MethodChannel para chamar a API nativa (consulte "Escrevendo código específico da plataforma personalizado" no flutter.dev). Onde posso registrar o MethodChannel quando o método configureFlutterEngine é removido?
Kamil Svoboda
Não tenho experiência em escrever código específico de plataforma. Lamento não poder ajudar com essa informação. Espero que você tenha encontrado uma resposta.
Axes Grinds
1

Adicionei apenas a classe água como extra nas etapas do pacote Firebase Messaging e foi resolvido:

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
fonte