1

I have Flutter mobile app that is using Riverpod with hooks.

I have the following function that I would like to be called when the widget is disposed:

    useEffect(
      () {
        final firestoreRepo = 
          ref.read(firebaseFirestoreRepositoryProvider);

        return () async {
          try {
            // I get exception at this line.  
            // I need this future to be called when the
            // widget is disposed.  
            // Calling this future earlier is not userful
            // for my business logic.
            final relationship =
              await ref.read(relationshipWithProvider(pid).future);

            if (relationship?.unseen ?? false) {
              await firestoreRepo?.updateRelatinoship(pid: pid);
            }
          } catch (e, st) {
            // print error
          }
        };
      },
      [],
    );

I keep getting this error at the line shown in the comment above.

I/flutter ( 5967): Looking up a deactivated widget's ancestor is unsafe.
I/flutter ( 5967): At this point the state of the widget's element tree is no longer stable.

How can I sold this problem

Aimn Blbol
  • 907
  • 11
  • 20

2 Answers2

0

We can initially get our relationship and then await and use it:

    useEffect(
      () {
        final firestoreRepo = ref.read(firebaseFirestoreRepositoryProvider);

        final relationship = ref.read(relationshipWithProvider(pid).future);

        return () async {
          try {
            if (await relationship?.unseen ?? false) {
              await firestoreRepo?.updateRelatinoship(pid: pid);
            }
          } catch (e, st) {
            // print error
          }
        };
      },
      [],
    );

As far as I can tell, this won't contradict the logic of the business process, because one way or another, we'll have to make the relationshipWithProvider(pid) request early (when we initialize the widget) or late (when we delete the widget).

Ruble
  • 2,589
  • 3
  • 6
  • 29
  • That does not work for me. I need to get the relationship right at the time of the disposal because it might have changed. – Aimn Blbol Feb 06 '23 at 13:39
  • Maybe we should call an asynchronous function via callback? That is, you must have some action, after which the widget dispose (for example, leave the screen, while pressing the "back" button). We could call `updateRelatinoship()` there. – Ruble Feb 07 '23 at 06:51
0

I was able to solve the problem by moving the code into the WillPopScope widget like this. Code seems to be working so far.

     WillPopScope(
      onWillPop: () async {
        try {
          final relationship =
              await ref.read(relationshipWithProvider(pid).future);

          if (relationship?.unseen ?? false) {
            await ref
                .read(firebaseFirestoreRepositoryProvider)
                ?.updateRelatinoship(pid: pid);
          }
        } catch (e, st) {
          debugPrint('oolfa: ChatScreen - updateRelatinoship - error - $e');
          debugPrint('oolfa: ChatScreen - updateRelatinoship - stack- $st');
        }
        return true;
      },
      child: // rest of your code
``
Aimn Blbol
  • 907
  • 11
  • 20