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