Как получить данные push-уведомления FCM в сети флаттера и перенаправить пользователя на полученную ссылку в уведомлении?

avatar
Yash Kadiya
9 августа 2021 в 04:42
620
1
2

Я пытаюсь перенаправить пользователя на определенную страницу в сети флаттера по щелчку уведомления, до сих пор я получаю уведомление, последняя открытая страница отображается в браузере по щелчку уведомления, но я хочу, чтобы пользователь перенаправлялся на определенную страницу, например конкретный пост с использованием уникального идентификатора поста, но я не нашел других способов. Это происходит в сборке Android, но не происходит в веб-сборке.

просто взгляните на ServiceWorker.js в serviceworker.js даже console.log() не выполняется при получении уведомления.

messaging.setBackgroundMessageHandler(function (payload) {
    console.log(payload);
    const promiseChain = clients
        .matchAll({
            type: "window",
            includeUncontrolled: true
        })
        .then(windowClients => {
            for (let i = 0; i < windowClients.length; i++) {
                const windowClient = windowClients[i];
                windowClient.postMessage(payload);
            }
        })
        .then(() => {
            const title = payload.notification.title;
            const options = {
                body: payload.notification.body             
              };
            return registration.showNotification(title, options);
        });
    return promiseChain;
});
self.addEventListener('notificationclick', function (event) {
    console.log('notification received: ', event)
});

теперь логика отправки push-уведомлений FCM:

  @required String message,
  @required String fcmToken,
  @required String title,
  String type,
  String typeId,
}) async {
  await http
      .post(
    Uri.parse('https://fcm.googleapis.com/fcm/send'),
    headers: <String, String>{
      'Content-Type': 'application/json',
      'Authorization': 'key=$serverToken',
    },
    body: jsonEncode(
      <String, dynamic>{
        'notification': <String, dynamic>{
          "click_action": 'FLUTTER_NOTIFICATION_CLICK',
          'body': message,
          'title': '$title',
          'sound': 'default'
        },
        'priority': 'high',
        'data': <String, dynamic>{
          'click_action': 'FLUTTER_NOTIFICATION_CLICK',
          'id': '1',
          'status': 'done',
          'type': type ?? "",
          'typeId': typeId ?? "",
        },
        'to': fcmToken.toString().trim(),
      },
    ),
  )
      .then((value) {
    print("Notification Sent");
  });
  final Completer<Map<String, dynamic>> completer =
      Completer<Map<String, dynamic>>();

  // firebaseMessaging.configure(
  //   onMessage: (Map<String, dynamic> message) async {
  //     completer.complete(message);
  //   },
  // );
  return completer.future;
}

Теперь, как я обрабатываю получение уведомлений:

    print("in setup interacted message");
    const AndroidNotificationChannel channel = AndroidNotificationChannel(
      'high_importance_channel', // id
      'High Importance Notifications', // title
      'This channel is used for important notifications.', // description
      importance: Importance.max,
    );

    final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
        FlutterLocalNotificationsPlugin();

    await flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(channel);

    NotificationSettings notifSettings =
        await FirebaseMessaging.instance.requestPermission(
      alert: true,
      announcement: true,
      badge: true,
      carPlay: true,
      criticalAlert: true,
      provisional: true,
      sound: true,
    );

    if (notifSettings.authorizationStatus == AuthorizationStatus.authorized) {
      // Get any messages which caused the application to open from
      // a terminated state.
      try {
        RemoteMessage initialMessage =
            await FirebaseMessaging.instance.getInitialMessage();

        // If the message also contains a data property with a "type" of "post",
        // navigate to a post screen
        if (initialMessage != null && initialMessage.data['type'] == 'post') {
          await Navigator.push(
            context,
            new MaterialPageRoute(
              builder: (BuildContext context) => IndividualPostPage(
                postObjectId: initialMessage.data['typeId'],
              ),
            ),
          );
          print(initialMessage.data);
          initialMessage = null;
        }

        // Also handle any interaction when the app is in the background via a
        // Stream listener
        FirebaseMessaging.onMessageOpenedApp
            .listen((RemoteMessage message) async {
          print("here");
          if (message != null && message.data['type'] == 'post') {
            if (message.data['type'] == 'post') {
              await Navigator.push(
                context,
                new MaterialPageRoute(
                  builder: (BuildContext context) => IndividualPostPage(
                    postObjectId: message.data['typeId'],
                  ),
                ),
              );
            }
            print(message.data);
            message = null;
          }
        });
      } catch (e) {
        print("Error $e");
      }
    }
  }
Источник

Ответы (1)

avatar
PradeepKumar
29 апреля 2022 в 16:07
0
messaging.setBackgroundMessageHandler(function (payload) {
    console.log(payload);
    const promiseChain = clients
        .matchAll({
            type: "window",
            includeUncontrolled: true
        })
        .then(windowClients => {
            for (let i = 0; i < windowClients.length; i++) {
                const windowClient = windowClients[i];
                windowClient.postMessage(payload);
            }
        })
        .then(() => {
            const title = payload.notification.title;
 var click_action =payload.data.ui_route;//ui route is ur route

            const options = {
                body: payload.notification.body    ,
 data: {
                          click_action,
                          
                        }         
              };
            return registration.showNotification(title, options);
        });
    return promiseChain;
});
// Notification click event listener
self.addEventListener('notificationclick', e => {
data=e.notification.data.obj;
  // Close the notification popout
  e.notification.close();
  // Get all the Window clients
  e.waitUntil(clients.matchAll({ type: 'window' }).then(clientsArr => {
    // If a Window tab matching the targeted URL already exists, focus that;
    const hadWindowToFocus = clientsArr.some(windowClient => windowClient.url === e.notification.data.click_action ? (windowClient.focus(), true) : false);
    // Otherwise, open a new tab to the applicable URL and focus it.
    if (!hadWindowToFocus) clients.openWindow(e.notification.data.click_action).then(windowClient => windowClient ? windowClient.focus() : null);
  }));
});