handleTalkJSFCMBackgroundMessage function

Future<bool> handleTalkJSFCMBackgroundMessage(
  1. RemoteMessage firebaseMessage
)

Implementation

Future<bool> handleTalkJSFCMBackgroundMessage(
    RemoteMessage firebaseMessage) async {
  print("📘 Handling a background message: ${firebaseMessage.messageId}");

  print('📘 Message data: ${firebaseMessage.data}');

  if (firebaseMessage.notification != null) {
    print(
      '📘 Message also contained a notification: ${firebaseMessage.notification}',
    );
  }

  final data = firebaseMessage.data;
  StyleInformation styleInformation;
  styleInformation = MessagingStyleInformation(Person(name: 'me'));
  int showId;

  if (!(data['talkjs'] is String)) {
    print("📘 _onFCMBackgroundMessage: data['talkjs'] is NOT String");
    return false;
  }

  print("📘 _onFCMBackgroundMessage: data['talkjs'] is String");
  final Map<String, dynamic> talkjsData = json.decode(data['talkjs']);
  final String notificationId = talkjsData['conversation']['id'];

  if (!_showIdFromNotificationId.containsKey(notificationId)) {
    _showIdFromNotificationId[notificationId] = _nextId;
    _nextId += 1;
  }

  showId = _showIdFromNotificationId[notificationId]!;

  final timestamp =
      DateTime.fromMillisecondsSinceEpoch(talkjsData['timestamp']);

  final activeNotifications = _activeNotifications[notificationId];

  if (activeNotifications == null) {
    print("📘 _onFCMBackgroundMessage: activeNotifications == null");
    _activeNotifications[notificationId] = [data['talkjs']];

    final attachment = talkjsData['message']['attachment'];

    if (attachment != null) {
      print("📘 _onFCMBackgroundMessage: attachment != null");
      final picture = await _androidBitmapFromUrl(attachment['url']);
      if (picture != null) {
        print("📘 _onFCMBackgroundMessage: picture != null");
        styleInformation = BigPictureStyleInformation(picture);
      } else {
        print("📘 _onFCMBackgroundMessage: picture == null");
      }
    } else {
      print("📘 _onFCMBackgroundMessage: attachment == null");
      final sender = talkjsData['sender'];
      styleInformation = MessagingStyleInformation(
        Person(
          name: 'me',
        ),
        groupConversation:
            talkjsData['conversation']['participants'].length > 2,
        messages: [
          Message(
            talkjsData['message']['text'],
            timestamp,
            Person(
              icon: await _androidIconFromUrl(sender['photoUrl']),
              key: sender['id'],
              name: sender['name'],
            ),
          ),
        ],
      );
    }
  } else {
    print("📘 _onFCMBackgroundMessage: activeNotifications != null");
    activeNotifications.add(data['talkjs']);
    final messages = <Message>[];
    for (final talkjsString in activeNotifications) {
      final Map<String, dynamic> messageTalkjsData = json.decode(talkjsString);
      final messageTimestamp =
          DateTime.fromMillisecondsSinceEpoch(messageTalkjsData['timestamp']);
      final messageSender = talkjsData['sender'];

      messages.add(
        Message(
          messageTalkjsData['message']['text'],
          messageTimestamp,
          Person(
            icon: await _androidIconFromUrl(messageSender['photoUrl']),
            key: messageSender['id'],
            name: messageSender['name'],
          ),
        ),
      );
    }

    styleInformation = MessagingStyleInformation(
      Person(
        name: 'me',
      ),
      groupConversation: talkjsData['conversation']['participants'].length > 2,
      messages: messages,
    );
  }

  // Fetch the push notification settings from shared preferences.
  final preferences = await SharedPreferences.getInstance();
  final value = preferences.getString(ANDROID_SETTINGS);
  _androidSettings = AndroidSettings.fromJson(jsonDecode(value!));

  // We default to not playing sounds, unless a non-empty string is provided
  final playSound = _androidSettings!.playSound.isNotEmpty;
  RawResourceAndroidNotificationSound? sound;

  // We use the string 'default' for the default sound (for compatibility with the React Natve SDK)
  if (playSound && (_androidSettings!.playSound != 'default')) {
    sound = RawResourceAndroidNotificationSound(_androidSettings!.playSound);
  }

  final platformChannelSpecifics = NotificationDetails(
    android: AndroidNotificationDetails(
      _androidSettings!.channelId,
      _androidSettings!.channelName,
      channelDescription: _androidSettings!.channelDescription,
      importance: _androidSettings!.importance?.toLocalNotification() ??
          Importance.high,
      playSound: playSound,
      sound: sound,
      enableVibration: _androidSettings!.vibrate ?? true,
      vibrationPattern: _androidSettings!.vibrationPattern,
      channelShowBadge: _androidSettings!.badge ?? true,
      enableLights: _androidSettings!.lights ?? false,
      ledColor: _androidSettings!.lightColor,
      visibility: _androidSettings!.visibility?.toLocalNotification(),
      styleInformation: styleInformation,
    ),
  );

  await _flutterLocalNotificationsPlugin.show(
    showId, // id
    data['title'], // title
    data['message'], // body
    platformChannelSpecifics, // notificationDetails
    payload: data['talkjs'],
  );

  return true;
}