0

I am use Firestore transaction for avoid race condition of add more than 1 user to chat. If transaction timeout, I show error dialog.

But when I move this logic to Model2 with ChangeNotifier (and Provider) it now show error:

Unhandled Exception: A Model2 was used after being disposed. Once you have called dispose() on a Model2, it can no longer be used.

(No issue with Firestore transaction. This is expected):

PlatformException(9, Transaction failed all retries.: Every document read in a transaction must also be written in that transaction., null)

It seem ChangeNotifier is call dispose() too early?

This mean it not allow me to handle error of race condition because it is already dispose.

Model:

class Model2 extends ChangeNotifier {

...

bool userAdded;

      Future<bool> addUser() async {

    try {
      await Firestore.instance.runTransaction((transaction) async {
        DocumentSnapshot chatRoomDocSnapshot =
            await transaction.get(chatRoomDocRef);
        bool userInChat = await chatRoomDocSnapshot[‘userInChat'];

        if (userInChat == false) {
            await transaction.update(chatRoomDocSnapshot.reference, {
              ‘userInChat': true,
            });
        }
      });

    await chatUserRef.setData({
      ‘User’: user,
    });

      userAdded = true;
notifyListeners();



    } catch (e) {
print(e);
      userAdded = false;
notifyListeners();

    }
    return userAdded;
      }

Provider (in stateful widget):

fetchData();

return ChangeNotifierProxyProvider<Model1, Model2>(
initialBuilder: (_) => Model2(),
  builder: (_, model1, model2) => model2
    ..string = model1.string,
),
  child: Consumer<Model2>(
    builder: (context, model2, _) =>

...
await model2.addUser();
...

Anyone know solution?

Thanks!

Update:

Issue is not throw if I remove fetchData(); from build method before ChangeNotifierProxyProvider .

But why is this fix the issue?

FlutterFirebase
  • 2,163
  • 6
  • 28
  • 60
  • This snippet is not enough to reproduce the issue. It could be multiple things, like related to navigation or listeners not properly disposed. – Rémi Rousselet Aug 19 '19 at 15:41
  • @RémiRousselet Not issue with navigation because it still throw if I remove navigator. I am not call `dispose()` anywhere. `provider` handle `dispose()` automatic right? – FlutterFirebase Aug 19 '19 at 15:51
  • @RémiRousselet I have fix issue by remove function from `build` method. Why this fix issue? – FlutterFirebase Aug 19 '19 at 16:28
  • Ah, you're calling `fetchData` in the build method? – Rémi Rousselet Aug 19 '19 at 16:30
  • That's pretty bad. See https://stackoverflow.com/questions/52249578/how-to-deal-with-unwanted-widget-build – Rémi Rousselet Aug 19 '19 at 16:30
  • @RémiRousselet Thanks! But why this throw error with Model? I was expect different error for this – FlutterFirebase Aug 19 '19 at 16:33
  • I agree that the snippet you've provided is not enough for the community to clearly see whats wrong. Since you've mentioned that when `fetchData()` was removed from the build method, it could have something in it that was causing the error. Could you provide the [a minimal, complete and verifiable example](https://stackoverflow.com/help/minimal-reproducible-example) of your code? – MαπμQμαπkγVπ.0 Dec 03 '20 at 22:22

1 Answers1

0

Going through the comments, it's likely that calling fetchData() rebuilds the entire screen - calling the dispose() method. If you're still having issues, I suggest providing logs and the code inside fetchData() for better context.

Omatt
  • 8,564
  • 2
  • 42
  • 144