Unhandled exception: setState () called after dispose ()

Red-throated loon

I'm trying to use Firebase Messaging to receive a notification in my flutter app and display it in my app, but I keep getting errors:

/FLTFireMsgReceiver( 6823): broadcast received for message
E/flutter ( 6823): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: setState() called after dispose(): _TipsState#aa4df(lifecycle state: defunct, not mounted)
E/flutter ( 6823): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
E/flutter ( 6823): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
E/flutter ( 6823): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
E/flutter ( 6823): #0      State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1085:9)
E/flutter ( 6823): #1      State.setState (package:flutter/src/widgets/framework.dart:1120:6)
E/flutter ( 6823): #2      _TipsState.getNotification.<anonymous closure> (package:stock_baba/Screens/Tips.dart:38:9)
E/flutter ( 6823): #3      _rootRunUnary (dart:async/zone.dart:1434:47)
E/flutter ( 6823): #4      _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter ( 6823): #5      _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter ( 6823): #6      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter ( 6823): #7      _DelayedData.perform (dart:async/stream_impl.dart:591:14)
E/flutter ( 6823): #8      _StreamImplEvents.handleNext (dart:async/stream_impl.dart:706:11)
E/flutter ( 6823): #9      _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:663:7)
E/flutter ( 6823): #10     _rootRun (dart:async/zone.dart:1418:47)
E/flutter ( 6823): #11     _CustomZone.run (dart:async/zone.dart:1328:19)
E/flutter ( 6823): #12     _CustomZone.runGuarded (dart:async/zone.dart:1236:7)
E/flutter ( 6823): #13     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1276:23)
E/flutter ( 6823): #14     _rootRun (dart:async/zone.dart:1426:13)
E/flutter ( 6823): #15     _CustomZone.run (dart:async/zone.dart:1328:19)
E/flutter ( 6823): #16     _CustomZone.runGuarded (dart:async/zone.dart:1236:7)
E/flutter ( 6823): #17     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1276:23)
E/flutter ( 6823): #18     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter ( 6823): #19     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

The PushNotification class is a simple class with the string fields title, body, dataTitle, and dataBody. My code is below.

class _TipsState extends State<Tips> {
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
  final List<PushNotification> messages = [];
  PushNotification? _notificationInfo;

  @override
  void initState() {
    getNotification();
    super.initState();
  }

  void getNotification() async {
    NotificationSettings settings =
        await _firebaseMessaging.requestPermission();

    if (settings.authorizationStatus == AuthorizationStatus.authorized) {
      print("Permission granted!");

      FirebaseMessaging.onMessage.listen((RemoteMessage message) {
        PushNotification notification = PushNotification(
            title: message.notification?.title,
            body: message.notification?.body,
            dataTitle: message.data['title'],
            dataBody: message.data['body']);

        setState(() {
          _notificationInfo = notification;
        });

        if (notification != null) {
          showSimpleNotification(Text(_notificationInfo!.title!),
              duration: Duration(seconds: 2),
              subtitle: Text(_notificationInfo!.body!));
        }
        print(notification);
        print(message.data);
      });
    } else {
      print("Permission declined!");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: messages.isEmpty
          ? Container()
          : ListView(
              children: [Text(messages[0].title!)],
            ),
    );
  }
}

I tried to wrap setState () with mounted () but it didn't work.

How can I resolve this issue and display incoming call notifications in the app?

Benten

Here is my code and how it works. Copy the code to create and paste the darts class. Notifications start working

Use the plugin there

  firebase_core: ^1.11.0
  firebase_messaging: ^11.2.5
  flutter_local_notifications: ^9.2.0
import 'dart:convert';
import 'dart:math';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:vcare/firebase_options.dart';

class NotificationHelper {
  NotificationDetails get _ongoing {
    const androidChannelSpecifics = AndroidNotificationDetails(
      'customer-channel-id',
      'customer-channel-name',
      importance: Importance.max,
      priority: Priority.high,
      ongoing: false,
      autoCancel: true,
    );
    const iOSChannelSpecifics = IOSNotificationDetails();
    return const NotificationDetails(android: androidChannelSpecifics, iOS: iOSChannelSpecifics);
  }

  // Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  // If you're going to use other Firebase services in the background, such as Firestore,
  // make sure you call `initializeApp` before using other Firebase services.
  // await initFirebase();
  // }

  configure() async {
    await initFirebase();
    FirebaseMessaging messaging = FirebaseMessaging.instance;
    await requestPermission(messaging);
    final String? token = await messaging.getToken();

    // FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

    final notification = await setupLocalNotification();
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      showNotification(
        notification,
        title: message.notification?.title,
        body: message.notification?.body,
        payload: message.data,
        type: _ongoing,
      );
    });

    return token;
  }

  Future<void> requestPermission(FirebaseMessaging messaging) async {
    await messaging.requestPermission(
      alert: true,
      announcement: false,
      badge: true,
      carPlay: false,
      criticalAlert: false,
      provisional: false,
      sound: true,
    );
  }

  Future<void> initFirebase() async {
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );
  }

  setupLocalNotification() async {
    const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings(
      'notification_icon',
    );
    final IOSInitializationSettings initializationSettingsIOS = IOSInitializationSettings(
      onDidReceiveLocalNotification: (int id, String? title, String? body, String? payload) {},
    );
    final InitializationSettings initializationSettings = InitializationSettings(
      android: initializationSettingsAndroid,
      iOS: initializationSettingsIOS,
    );
    var notification = FlutterLocalNotificationsPlugin();
    await notification.initialize(initializationSettings, onSelectNotification: (_) {});
    return notification;
  }

  showNotification(FlutterLocalNotificationsPlugin notifications,
      {required String? title, required String? body, required NotificationDetails type, required payload}) {
    notifications.show(Random().nextInt(100), title, body, type, payload: json.encode(payload ?? {}));
  }
}

Then call this class in the main.dart file. Here is the code

   WidgetsFlutterBinding.ensureInitialized();
      String? token = await NotificationHelper().configure();
    
     _storeFCMToken(token);

      print("deviceToken $token");

Please let me know if you have any problems. If you think this code is helping you, please mark my answer as approved

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324200781&siteId=291194637