supabase-flutter
supabase-flutter copied to clipboard
Postgres Changes don't closes connection on flutter web 'hot reload'
After initiating a postgres changes subscription at app start everything works fine. After hot reload/hot restart seem like the old subscription wasn't 'disposed', and the listener function is called twice. it happens only on flutter web , android works fine. I guess its kind a WebSocket problem , but maybe somebody had a similar problem and had a workaround. The only workaround i found is to refresh browser after hot restart/reload. Its disconnects all previous web sockets.
code example:
RealtimeChannel s = client .channel('public:$classId') .onPostgresChanges( event: PostgresChangeEvent.all, schema: 'public', table: classId, callback: (payload) { var m = payload.newRecord['model']; T cm = fromMap(m); listener(cm); }) .subscribe();
Would love to see this fixed as it is quite annoying.
I have found a workaround for now. Basically, just store the instance of the channel in a global variable whenever you subscribe. and clear it when You unsubscribe. Also store a local instance of the channel. In the callback compare the two instances with identical, and if they are not, that means the listener is from the old instance, so just ignore it by returning.
Here is some code:
RealtimeChannel? _channelInstance;
class ChannelListener {
late RealtimeChannel _channel;
void subscribe() {
_channel = SupabaseClient('url', 'anonKey')
.channel('public.*')
.onPostgresChanges(
event: PostgresChangeEvent.update,
schema: 'public',
callback: (payload) {
// Add this to every callback you have:
if (!identical(_channel, _channelInstance)) {
return;
}
// Your code here
},
)
.subscribe(
(status, error) {
if (!identical(_channel, _channelInstance)) {
return;
}
},
);
_channelInstance = _channel;
}
Future<void> unsubscribe() async {
_channelInstance = null;
await _channel.unsubscribe(Duration.zero);
}
}
This is just a basic implementation, what I just scraped from my project. Maybe it could be done even simpler, but at least it works for me. You may also add some logging call to that if statement if you want to see that it was really catched.
But basically, this is it.
I've experienced this as well while developing with this packager, but this seems more like a flutter issue. See https://github.com/flutter/flutter/issues/69949 so I'm unsure how this should be handled.
This is js proplem from web part. There is no way to stop the websockets from dart side. On the other hand, when flutter hotreloads, it dont refresh the browser. So the old js sockets still work
On Thu, Dec 12, 2024, 23:00 Vinzent @.***> wrote:
I've experienced this as well while developing with this packager, but this seems more like a flutter issue. See flutter/flutter#69949 https://github.com/flutter/flutter/issues/69949 so I'm unsure how this should be handled.
— Reply to this email directly, view it on GitHub https://github.com/supabase/supabase-flutter/issues/1088#issuecomment-2540097372, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGD2DATH24PNV6LUUGWQL4T2FIBQRAVCNFSM6AAAAABSQRHRK2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNBQGA4TOMZXGI . You are receiving this because you authored the thread.Message ID: @.***>