В Flutter, как мы используем Firebase Messaging onBackgroundMessage для создания уведомлений, используя flutter_local_notifications? - PullRequest
3 голосов
/ 06 января 2020

Мы работаем над зашифрованным приложением чата, в котором мы используем Firebase Messaging для уведомлений о данных. Некоторые клиентские логики c необходимо выполнить после получения уведомления о данных, прежде чем показывать действительное уведомление пользователю. Например, номер телефона должен быть переведен на местное имя контакта. Этот перевод выполняется путем поиска по карте, которая уже доступна глобально.

Уведомления о данных принимаются очень хорошо, а также вызывается обратный вызов onBackgroundMessage. Однако кажется невозможным получить доступ к любому состоянию из функции onBackgroundMessage. Например, печать номера телефона вошедшего в систему пользователя возвращает ноль. Печать этой же глобальной переменной из обратного вызова onMessage работает просто отлично.

Запуск flutter_local_notifications из onMessage работает нормально, но, опять же, вообще не работает из onBackgroundMessage, так как «не удалось найти реализацию метода .show () ». На данный момент он утверждает, что flutterLocalNotificationsPlugin имеет значение null, что на самом деле не так.

Нам кажется, что onBackgroundMessage не имеет доступа ни к чему, что предоставляет приложение, как только приложение становится фоновым. Нужно что-то сделать, чтобы часть контекста / контекста стала доступна фоновому процессу. На данный момент это будет в основном плагин flutter_local_notifications во всей его полноте, а также список локальных контактов для перевода номера телефона в имя.

Кто-нибудь знает, как это сделать?

Вот код:

FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
final _chatRepository = ChatRepository();

Future<dynamic> backgroundMessageHandler(Map<String, dynamic> message) async {
  if(message.containsKey('data')) {
    await _showNotification(message);
    return Future<void>.value();
  }
}

Future _showNotification(message) async {
  List<String> numbers = [];
  numbers.add(message['data']['sender']);
  var name = await _chatRepository.translatePhoneNumbersToChatName(numbers);
  var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
      'channel id', 'channel name', 'channel description',
      importance: Importance.Max, priority: Priority.High);
  var iOSPlatformChannelSpecifics = new IOSNotificationDetails();
  var platformChannelSpecifics = new NotificationDetails(
      androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
  await flutterLocalNotificationsPlugin.show(
    0,
    name,
    message['data']['body'],
    platformChannelSpecifics,
    payload: message['data']['body'],
  );
}

class NotificationHandler {
  final FirebaseMessaging fcm = FirebaseMessaging();
  StreamSubscription iosSubscription;
  String deviceToken = "";

  Future<void> initialize() async {
    flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
    var initializationSettingsAndroid =
    new AndroidInitializationSettings('@mipmap/ic_launcher');
    var initializationSettingsIOS = new IOSInitializationSettings(onDidReceiveLocalNotification: onDidReceiveLocalNotification);
    var initializationSettings = new InitializationSettings(initializationSettingsAndroid, initializationSettingsIOS);
    flutterLocalNotificationsPlugin.initialize(initializationSettings, onSelectNotification: onClickNotification);

    fcm.configure(
      onMessage: (Map<String, dynamic> message) async {
        if(message.containsKey('data')) {
          print(message);
          _showNotification(message);
        }
      },
      onBackgroundMessage: Platform.isIOS
          ? null
          : backgroundMessageHandler,
      onLaunch: (Map<String, dynamic> message) async {
        if(message.containsKey('data')) {
          print(message);
          _showNotification(message);
        }
      },
      onResume: (Map<String, dynamic> message) async {
        if(message.containsKey('data')) {
          print(message);
          _showNotification(message);
        }
      },
    );
    _updateDeviceToken();
  }
.
.
.

Of course, the initialize above is called early on in the application lifecycle.

Ответы [ 2 ]

0 голосов
/ 08 января 2020

Этот плагин объясняет все это лучше, чем я, но так получилось, что фон - это совершенно другой изолят / контекст, и поэтому он не имеет доступа ни к каким плагинам, если они используют старый (до Flutter 12) API. https://pub.dev/packages/android_alarm_manager#flutter - android -embedding-v1

Встраивание v1 требует регистрации всех подключаемых модулей, к которым вы хотите получить доступ из фона. Благодаря этому flutter_local_notifications работает должным образом.

К сожалению, документации по FCM очень не хватает.

0 голосов
/ 06 января 2020
class NotificationHandler {
  static final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); // make it a static field of the class
  // ...
}

Future _showNotification(message) async {
  // ...
  await NotificationHandler.flutterLocalNotificationsPlugin.show( // access it
    // ...
  );
}

Надеюсь, это работает для вас.

...