firstly i would appreciate the way you described you concern in that detailed way.
Packages required to be added in pubspec.yaml file:
shared_preferences
it will be used to to store data in offline mode. for good understanding lets see a use case i.e.
- user did some changes in offline mode and exits the app before
connection is restored in that case added data could lost.
- user did some change lets assume user added item in offline and if user added again second item before connection is restored previous added item or data may lost.
so to overcome these sort of conditions, would prefer to store data locally then ones connection is restored the data will sent to server.
connectivity package
we will use this package to check weather we are connected to internet.
socket_io_client
for making request to server we usually have two options one is this web socket and other is http request.
in online mode we usually uses http request as it is less complex while implementing comparatively although websocket is used in online mode when we don't want to see loading or request hit time as websocket only connects to server one time after that can directly emit and fetch data from server.
working:-
step 1 firtly check if we are online or offline if offline then store the data changed or added locally (if needed try to store data in list form and add each time the user adds data as item of list, later the whole list or array will send to server)
//checking for network
Future<bool> checkConnection() async{
var connectivityResult = await(Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
return true;
} else if (connectivityResult == ConnectivityResult.wifi) {
return true;
}
return false;
}
if network status is false store data locally
List<String> listAdded = pref.getStringList("key") ?? [];
ticketCollectorObject.add(json.encode(newDataList));
pref.setStringList("key", listAdded);
step 2 send data to server
now we have to connect websocket to backend and ones connection is established can emit or send data to socket.
using this can connect to web socket
void connectToServer() async {
try {
String token = token;
SharedPreferences pref = await SharedPreferences.getInstance();
// Configure socket transports must be sepecified
IO.Socket socket = IO.io(
'http:// host url',
OptionBuilder().setTransports(['websocket']) // for Flutter or Dart VM
.setExtraHeaders({'token': token}) // optional
.build());
// Connect to websocket
socket.connect();
socket.onConnect((_) {
print('connection successful with id: ${socket.id}');
List<String> offlineData =
pref.getStringList("key");
List<Map<String, dynamic>> listObject = [];
for (int i = 0; i < offlineData.length; i++) {
listObject.add(jsonDecode(offlineData[i]));
}
String dataToSend = jsonEncode(listObject);
print(dataToSend);
//response from server will be printed
socket.on(
'response',
(data) {
print(data);
if (data['message'] == "Success")
//as data was sent successfully so have to clean locally stored data
pref.setStringList("key", []);
},
);
print("status of socket with server connedction : ${socket.connected}");
socket.on('disconnect', (_) => print('disconnect'));
socket.on('fromServer', (_) => print(_));
} catch (e) {
print(e.toString());
}
}
call this connectToServer() function in initstate((){}) of home page as well with the send button on the screen so that even if users closes the app or restart the app the data will be updated automatically
ones data is emited after success connection of socket with server the socket keep on trying to send data till requests hits successfully so in offline mode ones we call connectToServer() the data will be sent to server ones internet is restored without any user interaction automatically.
notes:
- make surethe version of socket used backend and front part should be same.
- server url should be "http " not "https".