Приложение Flutter - невозможно добавить фоновую обработку уведомлений - PullRequest
0 голосов
/ 25 октября 2019

У меня есть класс маршрутизатора уведомлений, например:

  static FirebaseMessaging get fbMessaging {
    if (_firebaseMessaging == null) _firebaseMessaging = FirebaseMessaging();
    return _firebaseMessaging;
  }

  static Map<String, NotificationCallback> _onNewsletterCallbackList = {};
  static Map<String, NotificationCallback> _onMessageCallbackList = {};
  static Map<String, NotificationCallback> _onDiaryUpdatedCallbackList = {};
  static Map<String, NotificationCallback> _onUpgradeNeededCallbackList = {};

  static String subjectItemId(Map data) {
    return data['id'];
  }


  static void configure() {
    if (_configured) return;
    fbMessaging.configure(
      onResume: _resumeRouter,
      onLaunch: _launchRouter,
      onMessage: _notificationRouter,
//      onBackgroundMessage: _backgroundMessage,
    );
    _configured = true;
  }

//-- SNIP ALL THE ROUTING FUNCTIONS --

onMessage работает, когда приложение находится на переднем плане. _notificationRouter - это статический метод этого класса.

_backgroundMessage - это «глобальная» функция (вне какого-либо класса), и она просто печатает уведомление на данный момент.

Future<dynamic> _backgroundMessage(Map<String, dynamic> message) async {
  print('NR: Enter: _backgroundMessage');
  print(message);
}

Если язакомментируйте строку, чтобы настроить onbackgroundmessage, которое приложение закрывает с исключением.

D/AndroidRuntime(18376): Shutting down VM
E/AndroidRuntime(18376): FATAL EXCEPTION: main
E/AndroidRuntime(18376): Process: com.sample.dev, PID: 18376
E/AndroidRuntime(18376): java.lang.RuntimeException: Unable to create service io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService: java.lang.RuntimeException: PluginRegistrantCallback is not set.
E/AndroidRuntime(18376):    at android.app.ActivityThread.handleCreateService(ActivityThread.java:3544)
E/AndroidRuntime(18376):    at android.app.ActivityThread.access$1300(ActivityThread.java:199)
E/AndroidRuntime(18376):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1666)
E/AndroidRuntime(18376):    at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime(18376):    at android.os.Looper.loop(Looper.java:193)
E/AndroidRuntime(18376):    at android.app.ActivityThread.main(ActivityThread.java:6669)
E/AndroidRuntime(18376):    at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(18376):    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
E/AndroidRuntime(18376):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
E/AndroidRuntime(18376): Caused by: java.lang.RuntimeException: PluginRegistrantCallback is not set.
E/AndroidRuntime(18376):    at io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService.startBackgroundIsolate(FlutterFirebaseMessagingService.java:157)
E/AndroidRuntime(18376):    at io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService.onCreate(FlutterFirebaseMessagingService.java:77)
E/AndroidRuntime(18376):    at android.app.ActivityThread.handleCreateService(ActivityThread.java:3532)
E/AndroidRuntime(18376):    ... 8 more

Как только это произойдет, комментирование строки НЕ позволяет приложению запускаться снова, пока я не выполню «Очистить данные» (Удалитьхранилище приложений). Затем, если я откомментирую строку, чтобы снова подключить функцию, состояние приложения, похоже, снова будет повреждено.

Мне трудно понять, как настроить файл AndroidManifest.xml, потому что у меня сначала естьотдельный файл для каждого «аромата», но также имеет более одного значения «click_action».

На данный момент, чтобы упростить проблему, я закомментировал дополнительные действия нажатия из манифеста:

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="FLUTTER_NOTIFICATION_CLICK" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

<!--            <intent-filter>-->
<!--                <action android:name="ECHO_CLICK" />-->
<!--                <category android:name="android.intent.category.DEFAULT" />-->
<!--            </intent-filter>-->

<!--            <intent-filter>-->
<!--                <action android:name="child" />-->
<!--                <category android:name="android.intent.category.DEFAULT" />-->
<!--            </intent-filter>-->
<!--            <intent-filter>-->
<!--                <action android:name="school" />-->
<!--                <category android:name="android.intent.category.DEFAULT" />-->
<!--            </intent-filter>-->
<!--            <intent-filter>-->
<!--                <action android:name="staff" />-->
<!--                <category android:name="android.intent.category.DEFAULT" />-->
<!--            </intent-filter>-->
<!--            <intent-filter>-->
<!--                <action android:name="deals" />-->
<!--                <category android:name="android.intent.category.DEFAULT" />-->
<!--            </intent-filter>-->

            <meta-data
                android:name="com.google.firebase.messaging.default_notification_channel_id"
                android:value="@string/default_notification_channel_id" />
            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />

В Resorts Res у меня одна и та же строка, определенная во всех вариантах: Идентификатор канала моего приложения

Нужно ли где-нибудь связывать это значение "Идентификатор канала" с чем-то?

Из-за отчаяния я добавил click_action как к части данных, так и к части полезных данных уведомлений, то есть на данный момент она дублирована. Во многих ответах на SE говорится, что это должно быть в части данных, но спецификация https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support говорит, что это должно быть поле части Уведомления

Как правильно настроить фоновые push-уведомления. Если я смогу заставить их работать минимально, я надеюсь внести несколько изменений:

a) Использовать InheritedWidget для ведения списка страниц / обратных вызовов, которые хотят получать информацию о полученных уведомлениях различных типов, и bУлучшить это далее, используя Streams для доставки уведомлений тем, но пока класс «Маршрутизатор» просто поддерживает карту функций и вызывает все функции для типа полученных уведомлений.

Это работает для запущенных уведомлений Foreground, поэтому вопрос заключается в том, как это сделать для фоновых уведомлений.

...