PluginRegistry не может быть преобразован в FlutterEngine

22

Как только я обновил флаттер до версии 1.12.13, я обнаружил эту проблему и не могу ее исправить. Я сделал так, как отправлено руководство по firebase_messaging, и получил следующую ошибку: «ошибка: несовместимые типы: PluginRegistry нельзя преобразовать в FlutterEngine GeneratedPluginRegistrant.registerWith (registry);« Мой код выглядит следующим образом:

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 секунд, чтобы вы могли поместить приложение в фоновом режиме и убедиться, что сообщение в фоновом режиме работает

DomingoMG
источник
Я пытался это ваше решение, но мне не удалось, в состояниях ONLAUNCH, ONRESUME и ONMESSAGE появились, только на ONBACKGROUND нет. Я поместил файл FirebaseCloudMessagingPluginRegistrant.java в ту же папку, что и Application.java, это так? Я надеюсь, что команда Flutter скоро решит эту проблему. К тому времени мне придется использовать версию 1.9.1, хотя я так сильно хочу использовать 1.12.13
Габриэль Г. Паван
Не могли бы вы создать проект и дать мне ссылку на ваш github, чтобы я мог скачать его и попытаться запустить его в моем тестовом проекте Firebase?
Габриэль Дж. Паван
Я обновил ответ, я пропустил важный факт, чтобы добавить.
DomingoMG
Я покидаю структуру, которая помогла мне отправлять push-уведомления с помощью dart
DomingoMG,
Это сработало. Не знаю почему, но это так. Надеюсь, что команда флаттера исправит это в следующем выпуске
Ави
10

Порт кода DomingoMG для Kotlin можно найти ниже. Проверено и работает в марте 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 / studio / build /… . Тип программы уже присутствует: com.example.gf_demo.FirebaseCloudMessagingPluginRegistrant `` `
Камил
7

Замените вашу строку кода ниже:

GeneratedPluginRegistrant.registerWith(registry);

с этим:

FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
Мехрдад Сейрафи
источник
1
Это сработало ... просто не забудьте импортировать упомянутый класс. import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
Сион
1

В дополнение к ответу DomingoMG, не забудьте удалить

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

из файла mainactivity в папке Android. Если нет, вы получите ошибку.

Оси Шлифовальные
источник
Но где я могу зарегистрировать свой собственный MethodChannel, когда я удалю configureFlutterEngine?
Камил Свобода
Согласно ответу DomingoMG, FirebaseCloudMessagingPluginRegistrant.java уже выполняет регистрацию «registerWith ...», поэтому configureFlutterEngine больше не нужен. Это отвечает на ваш вопрос?
Оси размалывает
Я понимаю, что FirebaseCloudMessagingPluginRegistrant.java выполняет регистрацию вместо configureFlutterEngine. Но configureFlutterEngine - это место, где я могу зарегистрировать свой собственный MethodChannel для вызова нативного API (см. «Написание специального кода для платформы» на flutter.dev). Где я могу зарегистрировать MethodChannel, когда метод configureFlutterEngine удален?
Камиль Свобода
У меня нет опыта написания кода для платформы. Извините, что не могу помочь с этой информацией. Я надеюсь, что вы нашли ответ.
Axes Grinds
1

Я добавил только класс воды как дополнительный из шагов в пакете Firebase Messaging, и это было решено:

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
источник