PluginRegistry nie można przekonwertować na FlutterEngine

22

Jak tylko zaktualizowałem trzepotanie do wersji 1.12.13, znalazłem ten problem i nie mogę go naprawić. Zrobiłem tak, jak samouczek firebase_messaging i otrzymałem następujący błąd: „błąd: niezgodne typy: PluginRegistry nie można przekonwertować na FlutterEngine GeneratedPluginRegistrant.registerWith (register);” Mój kod jest następujący:

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
źródło
dostaję również ten błąd. jakieś rozwiązanie na razie?
ajonno
Nie. Próbowałem i nie mogłem
Gabriel G. Pavan,

Odpowiedzi:

21

Zaktualizowano 31 grudnia 2019 r.

Nie należy używać narzędzia do przesyłania wiadomości w chmurze Firebase do wysyłania powiadomień, ponieważ zmusza do korzystania z tytułu i treści.

Musisz wysłać powiadomienie bez tytułu i treści. mieć w tle aplikację, która powinna Ci pomóc.

Jeśli to zadziała, byłbym wdzięczny, gdybyś mógł oddać mi głos na tę odpowiedź, dziękuję.


Znalazłem tymczasowe rozwiązanie. Nie jestem pewien, czy to najlepsza poprawka, ale moje wtyczki działają zgodnie z oczekiwaniami i zakładam, że problem dotyczy rejestru dostarczonego przez io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService w linii 164.

Mój plik 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>

Moja aplikacja.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;
  }
}

Wyślij powiadomienie w rzutce:

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

Dodałem oczekiwanie na 5 sekund, abyś mógł umieścić aplikację w tle i sprawdzić, czy komunikat w tle jest uruchomiony

DomingoMG
źródło
Wypróbowałem twoje rozwiązanie, ale nie udało mi się, w stanach ONLAUNCH, ONRESUME i ONMESSAGE pojawiły się, tylko w ONBACKGROUND nie. Umieściłem plik FirebaseCloudMessagingPluginRegistrant.java w tym samym folderze co Application.java, prawda? Mam nadzieję, że zespół Flutter wkrótce rozwiąże ten problem. Do tego czasu będę musiał używać wersji 1.9.1, chociaż tak bardzo chcę używać wersji 1.12.13
Gabriel G. Pavan
Czy możesz stworzyć projekt i podać mi link do twojego github, abym mógł go pobrać i spróbować uruchomić go w moim projekcie testowym Firebase?
Gabriel G. Pavan
Zaktualizowałem odpowiedź, przegapiłem ważny fakt do dodania.
DomingoMG,
Opuszczam strukturę, która pomogła mi wysyłać powiadomienia wypychane za pomocą rzutki
DomingoMG,
To zadziałało. Nie jestem pewien dlaczego, ale tak się stało. Mam nadzieję, że zespół trzepotów naprawi to w następnym wydaniu
Avi
10

Port kodu DomingoMG do Kotlin można znaleźć poniżej. Testowane i działające w marcu 2020 r.

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
źródło
Cześć, `` Wykonanie nie powiodło się dla zadania ': app: mergeDexDebug'. > Wystąpił błąd podczas uruchamiania com.android.build.gradle.internal.tasks.Workers $ ActionFacade> com.android.builder.dexing.DexArchiveMergerException: Błąd podczas scalania archiwów dex: Dowiedz się, jak rozwiązać problem na developer.android.com / studio / build /… . Typ programu już obecny: com.example.gf_demo.FirebaseCloudMessagingPluginRegistrant ``
Kamil
7

Zamień poniższy wiersz kodu:

GeneratedPluginRegistrant.registerWith(registry);

z tym:

FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
mehrdad seyrafi
źródło
1
Działa ... pamiętaj tylko, aby zaimportować wspomnianą klasę. import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
zion
1

Oprócz odpowiedzi DomingoMG nie zapomnij usunąć

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

z pliku mainactivity w folderze android. Jeśli nie, pojawi się błąd.

Osie Grinds
źródło
Ale gdzie mogę zarejestrować własny MethodChannel, kiedy usunę configureFlutterEngine?
Kamil Svoboda
Zgodnie z odpowiedzią DomingoMG, FirebaseCloudMessagingPluginRegistrant.java już rejestruje „registerWith ...”, dlatego też configureFlutterEngine nie jest już potrzebny. Czy to jest odpowiedź na Twoje pytanie?
Axes Grinds
Rozumiem, że FirebaseCloudMessagingPluginRegistrant.java dokonuje rejestracji zamiast configureFlutterEngine. Ale configureFlutterEngine to miejsce, w którym mogę zarejestrować własny MethodChannel, aby wywoływać natywny interfejs API (zobacz „Pisanie niestandardowego kodu specyficznego dla platformy” na flutter.dev). Gdzie mogę zarejestrować MethodChannel po usunięciu metody configureFlutterEngine?
Kamil Svoboda
Nie mam doświadczenia w pisaniu kodu specyficznego dla platformy. Przepraszam, że nie mogę pomóc z tymi informacjami. Mam nadzieję, że znalazłeś odpowiedź.
Axes Grinds
1

Dodałem tylko klasę wody jako dodatkową część kroków w pakiecie Firebase Messaging i zostało to rozwiązane:

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
źródło