PluginRegistry не можна перетворити на FlutterEngine


22

Як тільки я оновив флетер до версії 1.12.13, я знайшов цю проблему і не можу її виправити. Я надіслав, як навчальний посібник firebase_messaging надіслав та отримав таку помилку: "помилка: несумісні типи: PluginRegistry не може бути перетворений у FlutterEngine GeneratedPluginRegistrant.registerWith (реєстр);" Мій код такий:

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

я також отримую цю помилку. якесь рішення поки що?
ajonno

Ні. Я спробував і не зміг
Габріель Г. Паван

Відповіді:


21

Оновлено 31 грудня 2019 року.

Не слід використовувати хмарний інструмент обміну повідомленнями Firebase для надсилання сповіщень, оскільки це змушує вас використовувати заголовок та тіло.

Ви повинні надіслати повідомлення без назви та органу. мати програму у фоновому режимі, яка повинна працювати для вас.

Якщо це працює для вас, я буду вдячний, якщо ви зможете проголосувати за цю відповідь, дякую.


Я знайшов тимчасове рішення. Я не впевнений, що це найкраще виправлення, але мої плагіни працюють, як очікувалося, і я припускаю, що проблема має бути з реєстром, який надає io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService на лінії 164.

Мій файл 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>

Моя заявка.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);
  }
}

Мій 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;
  }
}

Надіслати повідомлення в дартсі:

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

Я додав очікування тривалістю 5 секунд, щоб ви могли помістити програму на задній план і перевірити, чи працює повідомлення на задньому плані


Я спробував це ваше рішення, але я виявився невдалим. У станах ONLAUNCH з'явилися стани ONRESUME та ONMESSAGE, лише в ONBACKGROUND немає. Я помістив файл FirebaseCloudMessagingPluginRegistrant.java в ту ж папку, що і Application.java, чи правильно? Я сподіваюся, що команда Flutter скоро вирішить цю проблему. До цього часу мені доведеться використовувати версію 1.9.1, хоча я хочу погано використовувати 1.12.13
Габріель Г. Паван

Чи можете ви створити проект і надати мені посилання на ваш github, щоб завантажити і спробувати запустити його на моєму тестовому проекті Firebase?
Габріель Г. Паван

Я оновив відповідь, пропустив важливий факт, який слід додати.
DomingoMG

Я залишаю структуру, яка допомогла мені надсилати push-повідомлення з dart
DomingoMG

Це спрацювало. Не впевнений чому, але так і було. Сподіваюсь, що команда флетера виправить це у наступному випуску
Avi

10

Порт коду DomingoMG до Котліна можна знайти нижче. Тестували та працювали з березня 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
    }
  }
}

Привіт, `` `Виконання не виконано для завдання ': app: mergeDexDebug'. > Під час виконання com.android.build.gradle.internal.tasks.Workers $ ActionFacade сталася помилка під час виконання com.android.builder.dexing.DexArchiveMergerException: Помилка під час об’єднання архівів Dex: Дізнайтеся, як вирішити проблему на developer.android.com / студія / будувати /… . Тип програми вже присутній: com.example.gf_demo.FirebaseCloudMessagingPluginRegistrant `` `
Каміль

7

Замініть свій кодовий рядок нижче:

GeneratedPluginRegistrant.registerWith(registry);

з цим:

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

1
Це спрацювало ... просто пам'ятайте, щоб імпортувати згаданий клас. імпортувати io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
zion

1

Окрім відповіді ДомінгоМГ, не забудьте видалити

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

з файлу Mainactivity у папці android. Якщо ні, ви отримаєте помилку.


Але де я можу зареєструвати власний MethodChannel, коли я видалю configureFlutterEngine?
Каміль Свобода

Відповідно до відповіді DomingoMG, FirebaseCloudMessagingPluginRegistrant.java вже робить реєстрацію "registerWith ...", тож чому configureFlutterEngine більше не потрібен. Це відповідає на ваше запитання?
Axes Grinds

Я розумію, що FirebaseCloudMessagingPluginRegistrant.java робить реєстрацію замість configureFlutterEngine. Але configureFlutterEngine - це місце, де я можу зареєструвати свій власний MethodChannel для виклику нативного API (див. "Написання спеціального коду, що залежить від платформи" на flutter.dev). Де я можу зареєструвати MethodChannel, коли метод configureFlutterEngine видалено?
Каміль Свобода

Я не маю досвіду написання коду, що залежить від платформи. Вибачте, що я не можу допомогти з цією інформацією. Сподіваюся, ви знайшли відповідь.
Сокири перемелює

1

Я додав лише клас води як додатковий від кроків у пакеті повідомлень Firebase, і це було вирішено:

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;
}}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.