I am using Firestore in flutter application. Each time user launch the application it retrieves some data from Firestore Cloud.
QuerySnapshot dataSnapshot = await Firestore.instance
.collection('/data')
.getDocuments();
When user opens the application on first time, it required from him to connect online, to get the data, and as Firebase documents say
For Android and iOS, offline persistence is enabled by default. To disable persistence, set the PersistenceEnabled option to false.
So, it should save the data that application have been read before to retrieve it while the device is offline; so user can access application at anytime with the same data that have been read.
The problem is: it takes too long time to retrieve the data while the device is offline, with the same codes and nothing changed!.
I tried to configure how much time it takes? On offline, it takes about 8 minutes and 40 seconds. But while on online, it takes just 10 seconds, maybe less.
So how can I solve this problem?
============
I manged to get more logs about this problem, which after take a lot of time, and will start application with the offline saved data, it prints this log
This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.
And then take 3 second for example (not much time) and continue with the next works.
I did open a new issue in GitHub too.
Is there a way to limit the time it takes?
And finally, with the help of diegoveloper comment in GitHub issue, I have reached the solution.
await Firestore.instance .collection("Collection") .getDocuments(source: source)
was a good solution if I decided to check source each time and then use it or I can use it in starting of a new Flutter project, but now I already have a lot of codes that need a better solution. So I decided to fork the cloud_firestore package and edit it.
You can find it here: https://github.com/ShadyBoshra2012/flutterfire/tree/master/packages/cloud_firestore
// The source of which the data will come from.
static Source _source = Source.serverAndCache;
static Source get source => _source;
Future<void> settings(
{bool persistenceEnabled,
String host,
bool sslEnabled,
bool timestampsInSnapshotsEnabled,
int cacheSizeBytes,
Source source}) async {
await channel.invokeMethod<void>('Firestore#settings', <String, dynamic>{
'app': app.name,
'persistenceEnabled': persistenceEnabled,
'host': host,
'sslEnabled': sslEnabled,
'timestampsInSnapshotsEnabled': timestampsInSnapshotsEnabled,
'cacheSizeBytes': cacheSizeBytes,
});
if (source != null) _source = source;
}
query.dart
source = Firestore.source;
Line 92
document_reference.dart
source = Firestore.source;
Line 83
So you can use my forked repository in this way with using connectivity package from Google : https://pub.dev/packages/connectivity .
Add my forked repository in pubspec.yaml
file
cloud_firestore:
git:
url: https://github.com/ShadyBoshra2012/flutterfire.git
path: packages/cloud_firestore
Then in your first screen or main
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.none) {
await Firestore.instance.settings(source: Source.cache);
} else {
await Firestore.instance.settings(source: Source.serverAndCache);
}
and if you want to refresh the source when change the connection state:
StreamSubscription subscription;
void initState() {
super.initState();
// Check the internet connection after each change
// of the connection.
subscription = Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) async {
// Check the internet connection and then choose the appropriate
// source for it.
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.none) {
await Firestore.instance.settings(source: Source.cache);
} else {
await Firestore.instance.settings(source: Source.serverAndCache);
}
});
}
@override
void dispose() {
super.dispose();
subscription.cancel();
}
So I hope it works with everyone see it, and waiting for Flutter Team to code a better and better solution. Thanks for everyone has participated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With