Description
Describe the bug
We are using Supabase realtime for a chat app, and we are facing an unusual behavior with stream and channels
1) We have a global cubit that listens to room status name RoomStatusCubit
This RoomStatusCubit is initialized by listening to the room_status table:
initStream() {
var realstream = from('room_status')
.stream(primaryKey: ['id'])
.eq('to_uid', supabase.uid)
.order('at');
var subscription = realStream!.listen(
(event) {
log('realtime 0 listen event: $event');
emit(
state.copyWith(
rooms: RoomStatus.listFrom(event),
status: RealtimeStatus.result,
),
);
},
onError: (e, s) {
log('realtime 1 error: $e \ns:$s');
if (e.toString() == '' || e.toString() == '{}') return;
emit(state.copyWith(status: RealtimeStatus.error, error: e));
},
);
}
The above cubit has worked well for a while but has an issue when
- the internet disconnects and reconnects
- when for a long time there is no internet
3) when an error happens
To solve our above issue we have decided to close current channel and reinitalize stream
Future cancelStream() async {
try {
await subscription?.cancel();
subscription = null;
} catch (e, s) {
subscription = null;
loges(e, s, type: 'realtime cancelStream');
}
}
List<RealtimeChannel> get roomStatusChannels => supabase
.getChannels()
.where((e) => e.topic.contains('room_status'))
.toList();
Future cancelChannel() async {
for (RealtimeChannel c in roomStatusChannels) {
log('realtime cancel topic ${c.topic}');
await supabase.removeChannel(c);
}
await cancelStream();
}
The issue is when we call cancelChannel() and then initStream() the stream is not working anyway.
currently, we need to restart our app to solve this issue and we need a better solution for restarting superbase realtime channel to work correctly so users do not close and open their app.
To Reproduce
Steps to reproduce the behavior:
- Create an app with realtime stream in a cubit
- Try to cancelChannel() and initStream()
Expected behavior
Allow us to cancel a realtime stream and init stream again without any error and stream shall work like restarting an app
Version (please complete the following information):
On Linux/macOS
Please run dart pub deps | grep -E "supabase|gotrue|postgrest|storage_client|realtime_client|functions_client"
in your project directory and paste the output here.
│ └── supabase 1.10.0
│ ├── functions_client 1.3.2
│ ├── gotrue 1.11.2
│ ├── postgrest 1.5.0
│ ├── realtime_client 1.1.3
│ ├── storage_client 1.5.1
├── supabase_flutter 1.10.12
│ ├── supabase...
Additional context
We sometime also see heartbeat timeout
issue and not understand how this is related
and sometime see Bad state: Cannot add event after closing
error event or cubit is not closed and working correctly