PluginRegistry non può essere convertito in FlutterEngine


22

Non appena ho aggiornato il flutter alla versione 1.12.13 ho riscontrato questo problema e non riesco a risolverlo. Ho fatto come inviato il tutorial firebase_messaging e ho ricevuto il seguente errore: "errore: tipi incompatibili: PluginRegistry non può essere convertito in FlutterEngine GeneratedPluginRegistrant.registerWith (registro);" Il mio codice è il seguente:

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

sto ottenendo anche questo errore. qualche soluzione ancora?
ajonno,

No. Ci ho provato e non ci sono riuscito
Gabriel G. Pavan il

Risposte:


21

Aggiornato il 31 dicembre 2019.

Non è necessario utilizzare lo strumento di messaggistica cloud Firebase per inviare notifiche, poiché ti costringe a utilizzare il titolo e il corpo.

È necessario inviare una notifica senza il titolo e il corpo. avere l'applicazione in background, che dovrebbe funzionare per te.

Se funziona per te, ti sarei grato se potesse darmi un voto su questa risposta, grazie.


Ho trovato una soluzione temporanea. Non sono sicuro che questa sia la soluzione migliore, ma i miei plugin funzionano come previsto e presumo che il problema debba riguardare il registro fornito da io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService sulla linea 164.

Il mio file 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;
  }
}

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

Ho aggiunto un'attesa della durata di 5 secondi in modo da poter mettere l'applicazione in background e verificare che il messaggio in background sia in esecuzione


Ho provato è la tua soluzione ma non ho avuto successo, negli stati ONLAUNCH, ONRESUME e ONMESSAGE sono apparsi, solo su ONBACKGROUND no. Ho messo il file FirebaseCloudMessagingPluginRegistrant.java nella stessa cartella di Application.java, giusto? Spero che il team Flutter risolva presto questo problema. A quel punto dovrò usare la versione 1.9.1, anche se voglio usare così tanto la 1.12.13
Gabriel G. Pavan,

Potresti creare un progetto e darmi il link sul tuo github da scaricare e provare ad eseguirlo sul mio progetto di test Firebase?
Gabriel G. Pavan il

Ho aggiornato la risposta, ho perso un fatto importante da aggiungere.
DomingoMG

Lascio una struttura che mi ha aiutato a inviare notifiche push con dardo
DomingoMG

Questo ha funzionato. Non so perché, ma lo ha fatto. Spero che il team Flutter risolva questo problema nella prossima versione
Avi

10

Di seguito è riportato un porto del codice di DomingoMG per Kotlin. Testato e funzionante a marzo 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
    }
  }
}

Ciao, `` Esecuzione non riuscita per l'attività ': app: mergeDexDebug'. > Si è verificato un errore durante l'esecuzione di com.android.build.gradle.internal.tasks.Workers $ ActionFacade> com.android.builder.dexing.DexArchiveMergerException: errore durante l'unione degli archivi dex: scopri come risolvere il problema su developer.android.com / studio / build /… . Tipo di programma già presente: com.example.gf_demo.FirebaseCloudMessagingPluginRegistrant `` `
Kamil

7

Sostituisci la seguente riga di codice:

GeneratedPluginRegistrant.registerWith(registry);

con questo:

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

1
Ha funzionato ... ricorda di importare la classe menzionata. import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
zion,

1

Oltre alla risposta di DomingoMG, non dimenticare di rimuovere

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

dal file di attività principale nella cartella Android. In caso contrario, verrà visualizzato un errore.


Ma dove posso registrare il mio MethodChannel, quando rimuoverò configureFlutterEngine?
Kamil Svoboda,

Secondo la risposta di DomingoMG, FirebaseCloudMessagingPluginRegistrant.java fa già la registrazione di "registerWith ...", per questo motivo configureFlutterEngine non è più necessario. Questo risponde alla tua domanda?
Axes Grinds

Comprendo che FirebaseCloudMessagingPluginRegistrant.java esegue la registrazione anziché configureFlutterEngine. Ma configureFlutterEngine è il posto in cui posso registrare il mio MethodChannel per chiamare l'API nativa (vedere "Scrivere codice specifico per la piattaforma personalizzata" su flutter.dev). Dove posso registrare MethodChannel quando il metodo configureFlutterEngine viene rimosso?
Kamil Svoboda,

Non ho alcuna esperienza con la scrittura di codice specifico per la piattaforma. Mi dispiace non poterti aiutare con queste informazioni. Spero tu abbia trovato una risposta.
Axes Grinds

1

Ho aggiunto solo la classe d'acqua come extra dai passaggi nel pacchetto di messaggistica Firebase ed è stato risolto:

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;
}}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.