Supabase Flutter: Realtime updates stop after app was in background

102 views Asked by At

I have a view that is streaming data from a realtime-enabled table on Supabase.

But when the app is briefly in the background or the phone is locked, the realtime updates stop until I close and reopen the view.

I cannot replicate this on my local Supabase instance though.

class BSupaFooClient implements BFooClient {
  const BSupaFooClient({required this.supabaseClient});

  final SupabaseClient supabaseClient;

  @override
  Stream<Either<BFooStreamException, List<BFoo>>> foosStream() async* {
    try {
      final stream = supabaseClient
        .from('foos')
        .stream(primaryKey: ['id'])
        .eq('baa', 'fuzz')
        .limit(100)
        .order('short_id', ascending: true);

      await for (final foos in stream) {
        yield right(foos.map(BRawFoo.fromJSON).toList());
      }
    } catch (exception) {
      yield left(BRawFooStreamException.unknown);
    }
  }
}

class BFooRepository {
  const BFooRepository({required this.fooClient});

  final BFooClient fooClient;

  Stream<Either<BFooStreamException, List<BFoo>>> foosStream() async* {
    await for (final rawFoos in fooClient.foosStream()) {
      yield rawFoos.fold(
        (exception) => left(mapToException(exception)),
        (rawFoos) => right(mapToFoos(rawFoos)),
      );
    }
  }
}

class BFooStreamBloc extends Bloc<_BFooStreamEvent, BFooStreamState> {

  BFooStreamBloc({required this.repository}) : super(BFooStreamLoading()) {
    _subscribeToFoosStream();
    on<_BFooStreamUpdated>(_onUpdated);
  }

  final BFooRepository repository;

  late StreamSubscription<Either<BFooStreamException, List<BFoo>>> _foosSubscription;

  void _subscribeToFoosStream() {
    _foosSubscription = repository
        .foosStream()
        .listen((event) => add(_BFooStreamUpdated(data: event)));
  }

  void _onUpdated(
    _BFooStreamUpdated event,
    Emitter<BFooStreamState> emit,
  ) {
    event.data.fold(
      (exception) => emit(BFooStreamFailure(exception: exception)),
      (foos) => emit(BFooStreamSuccess(foos: foos)),
    );
  }

  @override
  Future<void> close() {
    _foosSubscription.cancel();
    return super.close();
  }
}

class BFoosView extends StatefulWidget {
  const BFoosView({super.key});

  @override
  State<BFoosView> createState() => _BFoosViewState();
}

class _BFoosViewState extends State<BFoosView> {
  @override
  Widget build(BuildContext context) {
    return BBlocBuilder<BFooStreamBloc, BFooStreamState>(
      builder: (context, bloc, state) {
        switch (state) {
          BFooStreamLoading() => const LinearProgressIndicator(),
          BFooStreamFailure() => const Center(child: Icon(Icons.error_rounded)),
          BFooStreamSuccess(foos: final foos) =>
            ListView(
              children: [
                ...foos.map((foo) => BFooItem(foo: foo)),
              ],
            ),
        };
      },
    );
  }
}
0

There are 0 answers