Flutterando / hasura_connect

Connect your Flutter/Dart apps to Hasura simply.
https://pub.dev/packages/hasura_connect
MIT License
204 stars 64 forks source link

Subscriptions stop working when app goes in backgroup, do not work anymore until I restart #103

Closed GiamBoscaro closed 1 year ago

GiamBoscaro commented 2 years ago

Good morning,

I have an app that uses some subscriptions to update some widgets in real time. It happens that, when you put the app in background or maybe you lock your phone etc., and then you bring the app in foreground again, the subscriptions stop working. The only way to make it work is to restart the application.

Is anyone having this problem? It is strange bacause it happens in testflight/production but not on the emulator nor when my phone is connected in debug mode.

tauamendonca commented 2 years ago

We already tested in debug and release mode, both on Android and iOS and are working to try to replicate this issue.

GiamBoscaro commented 2 years ago

We already tested in debug and release mode, both on Android and iOS and are working to try to replicate this issue.

Hello,

I solved doing this:

// main.dart

class _MyApp extends State<MyApp> with WidgetsBindingObserver {

  @override
  initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

 @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    switch (state) {
      // BACKGROUND
      case AppLifecycleState.paused:
        hasuraClient.disconnect();
        break;
      // FOREGROUND
      case AppLifecycleState.resumed:
        break;
      // FOREGROUND, NOT IN FOCUS
      case AppLifecycleState.inactive:
        break;
      // NO GUI
      case AppLifecycleState.detached:
        break;
    }
  }
// ....
// ....

hasuraClient is taken from a singleton service that manages the HasuraConnect client. I do this directly on the main.dart, then on the widgets that have a subscription I do this to resume the subscription when the app comes in foreground again:

// widget.dart
class _WidgetState extends State<Widget> with WidgetsBindingObserver {

  Snapshot? _subscription;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    WidgetsBinding.instance.addPostFrameCallback((_) => _subscribe());
  }

  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
    _subscription?.closeConnection!(_subscription!);
    _subscription?.close();
  }

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    switch (state) {
      case AppLifecycleState.paused:
        _subscription?.closeConnection!(_subscription!);
        _subscription?.close();
        break;
      case AppLifecycleState.resumed:
        _subscribe();
        break;
  }
// ....
// ....