Click here to Skip to main content
15,880,364 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am receiving notification on all state(foreground, background(on-Paused), terminated(on-Detached)) but it's redirecting me to the intended url only in(foreground and terminated state). Surprisingly, on receiving notification during foreground state, on-select notification works on-Background state(on-Paused) as well and I am redirected to my intended url. But the main problem is while recieving notification on-background state(on-Paused) without receiving notification on foreground at first, it just redirects me to where I was.

What I have tried:

Here is the code I am currently working on:
void afterInitFirebase() async {
  NotificationSettings settings = await _firebaseMessaging.requestPermission(
    alert: true,
    announcement: false,
    badge: true,
    carPlay: false,
    criticalAlert: false,
    provisional: false,
    sound: true,
  );

  await _firebaseMessaging
      .subscribeToTopic(topic)
      .onError((error, stackTrace) => {print(error)});

  await _firebaseMessaging.getToken().then((value) => {
        Preference.setString(fcm_token, value),
      });

  await _firebaseMessaging.setForegroundNotificationPresentationOptions(
    alert: true,
    badge: true,
    sound: true,
  );

  await _firebaseMessaging.getInitialMessage().then((RemoteMessage? message) {    
    if (message != null) {
      // _handleIncomingLinks();
      MyNotification().initMessaging(message, isPush: true);
    }
  });

  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    displayNotification(message);
  });

  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
    print("${message.from} =--> ON MESSAGE OPENED APP");
  });
}



void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  HttpOverrides.global = MyHttpOverrides();
  try {
    await Firebase.initializeApp().then((value) {
      afterInitFirebase();
    });
  } catch (e) {
    print(
      "EXCEPTION ON MAIN:" + e.toString(),
    );
  }

  final NotificationAppLaunchDetails? notificationAppLaunchDetails =
      await fitNotification.getNotificationAppLaunchDetails();
  final uri = await getInitialUri();
  String initialRoute = splash_page;
  String id = "0";
  if (notificationAppLaunchDetails!.didNotificationLaunchApp) {
    selectedNotificationPayload = notificationAppLaunchDetails.payload;

    print("payload $selectedNotificationPayload");

    var parts = selectedNotificationPayload?.split(SEPARATOR);

    if (parts != null) {
      if (parts[0] == "course" ||
          parts[0].toLowerCase() == "coursedetails" ||
          parts[0].toLowerCase() == "coursedetails") {
        id = parts[1];
        //course details page
        initialRoute = course_details;
      } else if (parts[0].toLowerCase() == "allcourse") {
        initialRoute = all_course;
        if (parts.length > 1) {
          id = parts[1];
        }
        print("payload: $initialRoute $id");
      } else if (parts[0].toLowerCase() == "allplan") {
        if (parts.length > 1) {
          id = parts[1];
        }
        initialRoute = "/allPlans";
      } else if (parts[0].toLowerCase() == "web") {
        id = parts[1];
        initialRoute = web_page;
      } else if (parts[0].toLowerCase() == "plan") {
        id = parts[1];
        initialRoute = plans_details_page;
      } else if (parts[0].toLowerCase() == "quiz") {
        initialRoute = web_page_entrance;
      } else if (parts[0].toLowerCase() == "wishlist") {
        initialRoute = route_wish_list;
      } else if (parts[0].toLowerCase() == "carts") {
        initialRoute = my_carts;
      } else {
        initialRoute = notification_page;
      }
    }
  }
  if (uri == null) {
  } else {
    String path = uri.toString();
    if (path.toLowerCase().contains("coursedetails") ||
        path.toLowerCase().contains("/home/course")) {
      String idStr = uri.path.substring(uri.path.lastIndexOf('/') + 1);
      id = idStr;
      initialRoute = course_details;
    }
  }

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  displayNotification(message);
}

void displayNotification(RemoteMessage message) {
  log(message.data.toString());
  MyNotification().initMessaging(message);
}


Here is MyNotification class:
<pre lang="Dart"><pre>const String SEPARATOR = "|";

class MyNotification {
  void initMessaging(RemoteMessage message, {isPush: true}) async {
    var androidInit = AndroidInitializationSettings('ic_notification');
    var iosInit = IOSInitializationSettings();
    var initSetting =
        InitializationSettings(android: androidInit, iOS: iosInit);
    await fitNotification.initialize(initSetting,
        onSelectNotification: onSelectNotification);

    var rand = new Random();
    int id = 1;
    String? title = "";
    String? body = "";
    String? icon = "";
    String? type = "";
    String? itemId = "";
    String link = "";  
    if (message.notification != null) {
      title = "${message.notification?.title}";
      body = "${message.notification?.body}";
      icon = "${message.notification?.android?.imageUrl}";

      if (Platform.isAndroid) {
        icon = "${message.notification?.android?.imageUrl}";
      } else {
        icon = "${message.notification?.apple?.imageUrl}";
      }
    }   
    if (message.data['source'] == "webengage") {
      isPush = true;
      Map<String, dynamic> messageData =
          jsonDecode(message.data['message_data']);    
      if (messageData.containsKey("title")) {
        title = messageData["title"];
        body = messageData["message"];
      }

      if (messageData.containsKey("expandableDetails")) {    
        Map<String, dynamic> expDetail = messageData["expandableDetails"];
        if (expDetail.containsKey("image")) {
          icon = expDetail["image"];
        }
        if (expDetail.containsKey("style")) {
          if (expDetail['style'] == "RATING_V1" ||
              expDetail['style'] == "CAROUSEL_V1") {
            isPush = false;
          }
        }
      }

      if (messageData.containsKey("custom")) {
        List<dynamic> customData = messageData['custom'];
        print("element1: ${customData.toString()}");

        customData.forEach((element) {
          Map<String, dynamic> maps = element;

          var key = maps['key'];
          var value = maps['value'];    
          if (key == "itemId") {
            itemId = value;
          }

          if (key == "type") {
            type = value;
          }
        });
      }
    } else {
      if (message.data.containsKey("icon")) {
        icon = message.data['icon'];
      }

      if (message.data.containsKey("title")) {
        title = message.data['title'];
        body = message.data['body'];
      }

      if (message.data.containsKey("type")) {
        type = message.data['type'];
      }

      if (message.data.containsKey("itemId")) {
        itemId = message.data["itemId"];
      }
    }

    if (title?.isNotEmpty == true && body?.isNotEmpty == true) {
      showNotification(rand.nextInt(1000), title, body, icon,
          "${type}$SEPARATOR${itemId}$SEPARATOR${icon}",
          isPush: isPush);
    }
  }

  Future<Uint8List> _getByteArrayFromUrl(String url) async {
    final http.Response response = await http.get(Uri.parse(url));
    return response.bodyBytes;
  }

  Future<void> showNotification(int notificationId, String? notificationTitle,
      String? notificationContent, String? icon, String payload,
      {String channelId = '1234',
      String channelTitle = 'Android Channel',
      String channelDescription = 'Default Android Channel for notifications',
      Priority notificationPriority = Priority.high,
      Importance notificationImportance = Importance.max,
      bool isPush = true}) async {
    //with icon
    if (icon != null && icon.isNotEmpty) {
      final String bigPicturePath =
          await _downloadAndSaveFile(icon, 'bigPicture.jpg');

      final BigPictureStyleInformation bigPictureStyleInformation =
          BigPictureStyleInformation(
        FilePathAndroidBitmap(bigPicturePath),
        largeIcon: FilePathAndroidBitmap(bigPicturePath),
      );

      var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
        channelId, channelTitle,
        channelDescription: channelDescription,
        playSound: false,
        importance: notificationImportance,
        priority: notificationPriority,
        styleInformation: bigPictureStyleInformation,
        icon: 'for_icon',
      );

      final IOSNotificationDetails iOSPlatformChannelSpecifics =
          IOSNotificationDetails(attachments: <IOSNotificationAttachment>[
        IOSNotificationAttachment(bigPicturePath)
      ]);
      final MacOSNotificationDetails macOSPlatformChannelSpecifics =
          MacOSNotificationDetails(attachments: <MacOSNotificationAttachment>[
        MacOSNotificationAttachment(bigPicturePath)
      ]);

      final NotificationDetails notificationDetails = NotificationDetails(
          iOS: iOSPlatformChannelSpecifics,
          macOS: macOSPlatformChannelSpecifics,
          android: androidPlatformChannelSpecifics);

      if (isPush) {
        await fitNotification.show(
          notificationId,
          notificationTitle,
          notificationContent,
          notificationDetails,
          payload: payload,
        );
      }
    } else {
      //with out icon
      var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
        channelId,
        channelTitle,
        channelDescription: channelDescription,
        playSound: false,
        importance: notificationImportance,
        priority: notificationPriority,
        icon: 'for_icon',
      );

      final NotificationDetails platformChannelSpecifics =
          NotificationDetails(android: androidPlatformChannelSpecifics);

      if (isPush) {
        await fitNotification.show(notificationId, notificationTitle,
            notificationContent, platformChannelSpecifics,
            payload: payload);
      }
    }

    var parts = payload.split(SEPARATOR);
    var now = new DateTime.now();
    var formatter = new DateFormat('yyyy-MM-dd HH:mm:ss');
    String formattedDate = formatter.format(now);

    NotificationModelData model = NotificationModelData(
        courseId: parts[1],
        icon: "$icon",
        title: notificationTitle.toString(),
        description: notificationContent.toString(),
        type: parts[0],
        notifyTime: formattedDate,
        isRead: false,
        id: now.millisecondsSinceEpoch.toString());
    var db = AppDatabase.instance;
    db.into(db.notificationModel).insert(model).then(
          (value) => print(value),
        );
  }

  Future<String> _downloadAndSaveFile(String url, String fileName) async {
    final Directory directory = await getApplicationDocumentsDirectory();
    final String filePath = '${directory.path}/$fileName';
    final http.Response response = await http.get(Uri.parse(url));
    final File file = File(filePath);
    await file.writeAsBytes(response.bodyBytes);
    return filePath;
  }

  Future<dynamic> onSelectNotification(String? payload) async {
    selectedNotificationPayload = payload;    
    var parts = payload!.split(SEPARATOR);

    if (parts[0].toLowerCase() == "course") {
      //course details page
      Navigator.pushNamed(
          navigatorKey.currentState!.overlay!.context, course_details,
          arguments: <String, String>{
            'course_id': parts[1],
            'thumbnail': parts[2]
          });
    } else if (parts[0].toLowerCase() == "web") {
      await Navigator.pushNamed(
          navigatorKey.currentState!.overlay!.context, web_page,
          arguments: <String, String>{'paymentUrl': "${parts[1]}"});
    } else if (parts[0].toLowerCase() == "allcourse") {
      Navigator.pushNamed(
          navigatorKey.currentState!.overlay!.context, all_course,
          arguments: <String, String>{'course_id': "${parts[1]}"});
    } else if (parts[0].toLowerCase() == "plan") {
      Navigator.pushNamed(
          navigatorKey.currentState!.overlay!.context, plans_details_page,
          arguments: <String, String>{'plan_id': "${parts[1]}"});
    } else if (parts[0].toLowerCase() == "allplan") {
      Navigator.pushNamed(
          navigatorKey.currentState!.overlay!.context, all_plans,
          arguments: <String, String>{'id': "${parts[1]}"});
    } else if (parts[0].toLowerCase() == "quiz") {
      Navigator.of(navigatorKey.currentState!.overlay!.context)
          .pushNamed(web_page_entrance);
    } else {
      //notification page
      await Navigator.pushNamed(
          navigatorKey.currentState!.overlay!.context, notification_page);
    }
  }


This is my WebPage class:

var url = "";

class WebPage extends StatefulWidget {
  void launchURL() async {
    if (await canLaunch(url))
      await launch(url);
    else
      throw "Could not launch $url";
  }

  @override
  _WebPageState createState() => _WebPageState();
}

class _WebPageState extends State<WebPage>{

  bool isLoading = true;
  final _key = UniqueKey();
  Map? _arguments;     

 var _webViewController;



@override
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
        return widget.launchURL();
      });
  }
  @override
  Widget build(BuildContext context) {
    _arguments = ModalRoute.of(context)!.settings.arguments as Map?;

    if (_arguments?.containsKey("paymentUrl") == true) {
      url = _arguments!["paymentUrl"];
    } else if (_arguments?.containsKey("course_id") == true) {
      url = _arguments!["course_id"];
    } else {
      print(url);
    }
    return Scaffold(
      body: SplashPage(),
    );
  }
}
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900