awesome_notifications icon indicating copy to clipboard operation
awesome_notifications copied to clipboard

Example of asBroadcastStream usage? - Bad state: Stream has already been listened to

Open bbence84 opened this issue 3 years ago • 13 comments

I am having the same issue as mentioned in #23 (Bad state: Stream has already been listened to.) However I also could not create a working example using the suggested "wrapper" class to expose the stream as a broadcast stream. Is there an example that shows how to do it?

Thanks!

bbence84 avatar Jun 11 '21 06:06 bbence84

I am having the same issue. also if anyone can help in telling me what is the best way of setting up the package. I am having trouble figuring out how I can handle the click listener at the very top of my application. right now I am listening to action stream on multiple screens initState(). and if I go back from screen and start the screen again I run into this error "Bad state: Stream has already been listened to". I have converted "MyApp" widget to stateful and listen to notification action on it's initState() but I can't navigate to any screen from there because the "context does not have a Navigator". Any help would be appreciated and if someone could link an example with FCM and Awesome package best configuration way that would be great.

muneebahmad0600 avatar Jun 11 '21 07:06 muneebahmad0600

A traditional stream can only be listened once. And it's totally fine with the notifications handling, because you gonna use it only in the first widget page. If i expose the streams to be converted into broadcast, so a notification could be lost, specially on actionStream, if the app takes time enought to initialize.

Take a look at this episode : Dart Streams - Flutter in Focus

And there is a lot of other details about how to do it appropriately, such as to avoid to open two consecutives notification's page.

But don't worry. There is a full example with this navigation redirection and all the other details about it in our application example folder.

I strongly recommend you to take a look at our example app and at the README file.

rafaelsetragni avatar Jun 11 '21 15:06 rafaelsetragni

I am also having the same issue, does anyone of you have a solution? I looked in the example app but still couldn't figure it out. I also closed the actionSink in the dispose method, but the error still occurs

roland-burke avatar Jun 17 '21 10:06 roland-burke

@rafaelsetragni If I start listening to the actions on one screen and then I move to the other one, I cannot navigate when the user clicks on a notification action because the widget (in which I was listening to the stream) has been dismounted hence it's context is "DEFUNCT". In your example you are listening to actions on the very first screen after App Widget. what if I am showing different screens depending upon if user is logged in or not ? where should I listen for action stream then ?

muneebahmad0600 avatar Jun 18 '21 08:06 muneebahmad0600

In my case, when I log in to the software -> logout -> login back in and get an error:

  • Bad state: Stream has already been listened to.

Because AwesomeNotifications().actionStream (createdStream, displayedStream, dismissedStream) can't cancel or stop when the app hasn't exited. Although before loggout the app I called:

  • AwesomeNotifications().actionSink.close();
  • await AwesomeNotifications().dispose();

Do you have a way to close the streamController completely or check stream is listeningning. Because when logging back in without completely exiting the application, it will encounter the case of listening stream twice. Is it possible to use StreamSubscription instead of StreamController ???. Thanks you!!.

tuemaytinh1981 avatar Oct 17 '21 03:10 tuemaytinh1981

await AwesomeNotifications().dispose(); should only be called when the app is gonna be closed.

Im changing awesome notification to not use streams, instead use static methods. But this feature will only be available on version 0.0.7. So, until there, streams can be listen only one time in the entire app.

rafaelsetragni avatar Oct 17 '21 04:10 rafaelsetragni

Yeh, thanks you. Your package is easy to use and awesome. Looking forward to your new update. You should pay attention to the solution to this case, almost every application has this case. I see FirebaseMessaging also use Stream:


FirebaseMessaging.onMessage.listen((RemoteMessage message) {
   // code ...
} 

/// The Stream contains the [RemoteMessage].
///
/// To handle messages whilst the app is in the background or terminated,
/// see [onBackgroundMessage].
  static Stream get onMessage =>
      FirebaseMessagingPlatform.onMessage.stream;
/// Returns a [Stream] that is called when a user presses a notification message displayed
/// via FCM.
///
/// A Stream event will be sent if the app has opened from a background state
/// (not terminated).
///
/// If your app is opened via a notification whilst the app is terminated,
/// see [getInitialMessage].
  static Stream get onMessageOpenedApp =>
      FirebaseMessagingPlatform.onMessageOpenedApp.stream;

Using the same method as you but without the same listening error as: Bad state: Stream has already been listened to.


AwesomeNotifications().actionStream.listen((ReceivedAction action) {
   // code
}

... Probably due to using static Stream !!!!.

tuemaytinh1981 avatar Oct 17 '21 08:10 tuemaytinh1981

In my case, when I log in to the software -> logout -> login back in and get an error:

  • Bad state: Stream has already been listened to.

Because AwesomeNotifications().actionStream (createdStream, displayedStream, dismissedStream) can't cancel or stop when the app hasn't exited. Although before loggout the app I called:

  • AwesomeNotifications().actionSink.close();
  • await AwesomeNotifications().dispose();

Do you have a way to close the streamController completely or check stream is listeningning. Because when logging back in without completely exiting the application, it will encounter the case of listening stream twice. Is it possible to use StreamSubscription instead of StreamController ???. Thanks you!!.

@tuemaytinh1981 I have the same case as you and i am unable to find the solution to the issue. If you have found the solution please can you share it here and explain me. Thanks for your help.

vaidikkamde avatar Jan 25 '22 06:01 vaidikkamde

can be listen only one time in the entire app.

Any solution to this?!?!

globalwebforce avatar Apr 25 '22 04:04 globalwebforce

The 0.7.0 beta version is already on live.

rafaelsetragni avatar Apr 25 '22 04:04 rafaelsetragni

In my case, when I log in to the software -> logout -> login back in and get an error:

  • Bad state: Stream has already been listened to.

Because AwesomeNotifications().actionStream (createdStream, displayedStream, dismissedStream) can't cancel or stop when the app hasn't exited. Although before loggout the app I called:

  • AwesomeNotifications().actionSink.close();
  • await AwesomeNotifications().dispose();

Do you have a way to close the streamController completely or check stream is listeningning. Because when logging back in without completely exiting the application, it will encounter the case of listening stream twice. Is it possible to use StreamSubscription instead of StreamController ???. Thanks you!!.

@tuemaytinh1981 I have the same case as you and i am unable to find the solution to the issue. If you have found the solution please can you share it here and explain me. Thanks for your help.

I found a fix for this by wrapping the AwesomeNotifications().actionStream inside a try catch block like so

try { AwesomeNotifications() .actionStream .listen((ReceivedNotification receivedNotification) async { if (kDebugMode) { print( 'Awesome notification Action Stream ${receivedNotification.payload}', ); } }); } catch (e) { if (kDebugMode) { print(e); } }

vaidikkamde avatar Apr 25 '22 05:04 vaidikkamde

In my case, when I log in to the software -> logout -> login back in and get an error:

  • Bad state: Stream has already been listened to.

Because AwesomeNotifications().actionStream (createdStream, displayedStream, dismissedStream) can't cancel or stop when the app hasn't exited. Although before loggout the app I called:

  • AwesomeNotifications().actionSink.close();
  • await AwesomeNotifications().dispose();

Do you have a way to close the streamController completely or check stream is listeningning. Because when logging back in without completely exiting the application, it will encounter the case of listening stream twice. Is it possible to use StreamSubscription instead of StreamController ???. Thanks you!!.

@tuemaytinh1981 I have the same case as you and i am unable to find the solution to the issue. If you have found the solution please can you share it here and explain me. Thanks for your help.

I found a fix for this by wrapping the AwesomeNotifications().actionStream inside a try catch block like so

try { AwesomeNotifications() .actionStream .listen((ReceivedNotification receivedNotification) async { if (kDebugMode) { print( 'Awesome notification Action Stream ${receivedNotification.payload}', ); } }); } catch (e) { if (kDebugMode) { print(e); } }

do you have any idea how to stop listening to notifications, when the user logout?

globalwebforce avatar Apr 25 '22 05:04 globalwebforce

Use inside of Statefull at initState. Its works for me.

@override
  void initState() {
    super.initState();
   AwesomeNotifications().actionStream.listen((receivedNotification) {
      print(receivedNotification);
      Navigator.of(context).pushNamed("/classpage");
 });
}

as suggested in one of the issues. Instead of :

class _MyHomePageState extends State<MyHomePage> {


   
   @override
  Widget build(BuildContext context) {
   // Listener
   AwesomeNotifications().actionStream().listen((event) {});
  //
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }

Do this:

class _MyHomePageState extends State<MyHomePage> {

 @override 
  void initState() {
   AwesomeNotifications().actionStream().listen((event) {});
   }

   
   @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }

This has been working for me like charm

mathiasgodwin avatar Aug 26 '22 16:08 mathiasgodwin

Hi! Sorry for taking so long to respond to your issue on GitHub. I was focused on releasing the new 0.7.0 version of awesome_notifications and awesome_notifications_fcm and i didn't had time enough to do both. But now I can answer all your questions.

So now i'm asking you to recreate this topic using the new issue template. There's a lot of missing informations that i need to understand your problem, and all the instructions are already in the new issue template. Also, remember to check beforehand if your issue was posted by another user.

So I will automatically close all previous issues so far. Sorry for the inconvenience and i will be waiting for your new issue request.

Thank you so much for your support!

rafaelsetragni avatar Sep 29 '22 17:09 rafaelsetragni