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)),
],
),
};
},
);
}
}