supabase-flutter
supabase-flutter copied to clipboard
Bug: Stream behaviour on connection lost and reconnect
Describe the bug
With the update to 1.2.3 , losing the connection doesn't trigger any error anymore. Also reconnecting to the internet doesn't change/trigger anything.
My current code (with v1.2.2)
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
class RealtimeGameService extends ChangeNotifier {
RealtimeGameService({
required this.client,
required this.primaryKey,
required this.tableName,
}) {
_init();
}
final SupabaseClient client;
final String tableName;
final List<String> primaryKey;
List<Map<String, dynamic>> data = [];
DateTime lastUpdateTime = DateTime.now();
bool isConnected = false;
bool isInitialLoading = true;
StreamSubscription<List<Map<String, dynamic>>>? _streamSubscription;
void _init() {
_streamSubscription?.cancel(); // Cancel any existing subscription
final liveDataStream =
client.from(tableName).stream(primaryKey: primaryKey);
_streamSubscription = liveDataStream.listen(
(List<Map<String, dynamic>> newData) {
print('works');
print('Received data: $newData');
_updateData(newData, true);
if (isInitialLoading) {
isInitialLoading = false; // Mark initial loading as complete
notifyListeners();
}
},
onError: (e) {
print('Error during realtime subscription: $e');
_updateData(data, false);
if (isInitialLoading) {
isInitialLoading = false; // Mark initial loading as complete
notifyListeners();
}
},
onDone: () {
print('Realtime subscription done');
},
);
}
void _updateData(List<Map<String, dynamic>> newData, bool newIsConnected) {
data = newData;
lastUpdateTime = newIsConnected ? DateTime.now() : lastUpdateTime;
isConnected = newIsConnected;
notifyListeners();
}
void reload() {
_init();
isInitialLoading = true;
notifyListeners();
}
@override
void dispose() {
_streamSubscription?.cancel();
super.dispose();
}
}
Expected behavior
- At least one single error should be thrown that the websocket lost connection
- It would be nice if the websocket reconnects it triggers the
onDataagain
Version (please complete the following information): ????????? realtime_client 1.2.2 ????????? supabase_flutter 1.10.18 ??? ????????? supabase 1.11.5 ??? ??? ????????? functions_client 1.3.2 ??? ??? ????????? gotrue 1.12.4 ??? ??? ????????? postgrest 1.5.1 ??? ??? ????????? realtime_client... ??? ??? ????????? storage_client 1.5.3
Thanks for opening this @coolusaHD
I'm assuming the reason why you want to receive error within onError when listening to stream is to restart the stream when the connection is lost, correct? We are working on making the .stream() method more reliable so that it will self-reconnect if the realtime connection gets lost for any reason. If this is implemented, would you say there is no need to have an API to detect if the stream lost its connection?
@dshukertjr
In my implementation I use the onError for notifiy the user that he no longer recieves the latest data. To reconnect the user itself have to press a button to retry/ reinit the stream subscription.
So to answer your question: No I dont use it to automatically reconnect to the stream.
Therefore it would be nice if the stream would automatically reconnect and recall the onData callback but it would be also nice (and essential for me) that at least the onError gets triggered once when the stream lost the connection.
Thanks for asking🙌
@dshukertjr Any ideas when the work on making the ".stream() method more reliable" is going to be finished? Or available for a first testing?
Any updates on this ? ✌️ @dshukertjr
Thanks for opening this @coolusaHD
I'm assuming the reason why you want to receive error within
onErrorwhen listening to stream is to restart the stream when the connection is lost, correct? We are working on making the.stream()method more reliable so that it will self-reconnect if the realtime connection gets lost for any reason. If this is implemented, would you say there is no need to have an API to detect if the stream lost its connection?
Is there an ETA on this? Stream is so buggy right now it is really difficult to trust it.
@dshukertjr
I had some freetime and testet a bit. The change of the _onConnError function also prevents that the onError function of the stream gets the error.
But thats not the only problem. If the connection fails the heartbeat should also fail and close the stream after 2 missed heartbeats. But that doesn't trigger anything.
So from my perspective I see why the flooding of errors should be prevented but without any error how can I know if my stream is still connected to the source?
I really like to update to the latest version but my app cant live without that 😅
Is there any change to make the error flooding optional or even fix it that it returns at least one error?
Thanks in advance. ✌️
I would also like to vote that at least an error message is displayed when the streams stop receiving data.
Supabase and the supabase_flutter package are such great products, but with faulty realtime support in certain cases, the package is simply not ready for production applications imho. This should at least be openly communicated to the customers. If someone knows a reliable workaround for the stream issues, I would love to know about it. I couldn't find one myself over the last months and that's holding us back.
Any official statement would be highly appreciated. Otherwise, I love everything about Supabase and would recommend it anytime.
Hope quick solve this issue. I also lost connect and do not receive error from stream.onError callback. It it difficult to fix it for the app developer.
I just built a ton on top of realtime SQL updates, assuming it would be easy to add in some reconnect logic once I got around to it... and this... seems like a pretty fundamental thing to prioritize
Has anyone figured out any workarounds?
Hi @dshukertjr, is there any update on the fix?
My issue is the connection gets lost when the app is in the background for a while. When the app becomes active again, it doesn't seem to automatically reconnect and thus only display the stale data which were received before the connection was lost.
I tried to work around this issue by listening to the app lifecycle change to manually reconnect. However, I am concerned of this approach because there's no way to manually close the stream right now (or at least I couldn't find a way to do it). This means that there could be multiple stream open simultaneously which may lead to memory leak.
Given that most of apps inherently will go to background for a long period of time, this seems to be a serious issue because app will only display stale data. In my case, I am sending a push notification whenever there's new chat message but when clicking on it to land on the chatroom, the latest message often is not present.
Will #1019 address this?
Will #1019 address this?
It looks like better error handling. If this will trigger the onError callback function in the
stream.listen() functionwould be nice and propably fix the error
With modified pubspec.yaml
realtime_client: ^2.2.1
supabase_flutter: ^2.6.0
supabase: ^2.3.0
dependency_overrides:
supabase_flutter:
git:
url: https://github.com/supabase/supabase-flutter/
ref: fix/realtime
path: ./packages/supabase_flutter
realtime_client:
git:
url: https://github.com/supabase/supabase-flutter
ref: fix/realtime
path: ./packages/realtime_client
supabase:
git:
url: https://github.com/supabase/supabase-flutter
ref: fix/realtime
path: ./packages/supabase
After I dissconnected the internet on the device the stream takes about 40s to check and then throws an error so my app can show that it is no longer connected to the internet. After reconnecting it instantly works again like before.
See #1019
@Vinzent03 @dshukertjr I'm gonna close this isse when #1019 gets merged ✌️ 🚀
With #1019 being merged now, these issues should be solved now. You can try them by upgrading supabase_flutter to 2.7.0. If you still experience any issues, please create a new issue.