Closed teolemon closed 2 years ago
@teolemon I wouldn't blame the 4G. But:
would that be possible to upload in the background? not sure about the UX, and there's probably already at least one issue with that.
I am doing this, we can easily force the upload to be in the background but then it's about how to notify the user when the work manager finishes its task of uploading Here's the apk, can I hear a ux suggestion on this How I retry in case of failure is like this
switch (counter) {
case 0:
duration = const Duration(seconds: 30);
break;
case 1:
duration = const Duration(minutes: 1);
break;
case 2:
duration = const Duration(minutes: 30);
break;
case 3:
duration = const Duration(hours: 1);
break;
case 4:
duration = const Duration(hours: 6);
break;
default:
duration = const Duration(days: 1);
break;
}
https://drive.google.com/file/d/1-UaDQtCi3mSwBN0WtvRQUBg39kR3OqIg/view?usp=sharing
how to notify the user when the work manager finishes its task of uploading
My personal opinion on that is that we should not notify the user. I don't see the point, users take photos, they assume they will be sent. If we really want to make this information available, then it would be more in the user's profile: # of photos sent + # of photos waiting to be sent.
If the question is just "how to notify the user", I assume we can do this with a provider. I would tend to agree with @stephanegigandet regarding UX.
To me, the biggest challenges here are:
isolate
? just async
?) that uploads the pictures and refreshes the product locally (that's where you would notify with your provider)@monsieurtanuki Trying with something like this, seemed to work real good, also had the apk here https://drive.google.com/file/d/1-UaDQtCi3mSwBN0WtvRQUBg39kR3OqIg/view?usp=sharing
the background process (isolate? just async?) that uploads the pictures and refreshes the product locally (that's where you would notify with your provider)
Was trying to do something with workanager
,added benefits would be the background scheduling and there's the retry method to try to upload multiple times(ios doesn't support retry by default)
@pragma(
'vm:entry-point') // Mandatory if the App is obfuscated or using Flutter 3.1+
void callbackDispatcher() {
Workmanager().executeTask(
(String task, Map<String, dynamic>? inputData) async {
// make a counter with task as key as it is unique for each task
final int counter = inputData!['counter'] as int;
// if task is greate than 4 , that means it has been executed 5 times
if (counter > 5) {
// returns true to let platform know that the task is completed
return Future<bool>.value(true);
}
Duration duration;
switch (counter) {
case 0:
duration = const Duration(seconds: 30);
break;
case 1:
duration = const Duration(minutes: 1);
break;
case 2:
duration = const Duration(minutes: 30);
break;
case 3:
duration = const Duration(hours: 1);
break;
case 4:
duration = const Duration(hours: 6);
break;
default:
duration = const Duration(days: 1);
break;
}
bool shouldRetry = false;
try {
final SendImage image = SendImage(
lang: ProductQuery.getLanguage(),
barcode: inputData['barcode'].toString(),
imageField:
ImageFieldExtension.getType(inputData['imageField'].toString()),
imageUri: Uri.parse(inputData['imageUri'].toString()),
);
final Status result = await OpenFoodAPIClient.addProductImage(
ProductQuery.getUser(),
image,
);
shouldRetry = result.error != null || result.status != 'status ok';
} catch (e) {
shouldRetry = true;
debugPrint(e.toString());
}
if (shouldRetry) {
inputData['counter'] = counter + 1;
Workmanager().initialize(callbackDispatcher, isInDebugMode: true);
Workmanager().registerOneOffTask(
task,
'ImageUploadWorker',
// constraints: Constraints(
// networkType: NetworkType.connected,
// ),
inputData: inputData,
initialDelay: duration,
);
return Future<bool>.error('Failed and it will try again');
} else {
return Future<bool>.value(true);
}
},
);
}
// To invoke
final Map<String, dynamic> inputData = <String, dynamic>{
'barcode': barcode,
'imageField': imageField.value,
'imageUri': File(imageUri.path).path,
'counter': 0,
};
await Workmanager().initialize(
callbackDispatcher, // The top level function, aka callbackDispatcher
isInDebugMode:
true // If enabled it will post a notification whenever the task is running. Handy for debugging tasks
);
final String uniqueId = 'ImageUploader_${barcode}_${imageField.value}';
await Workmanager().registerOneOffTask(
uniqueId, 'ImageUploadWorker',
inputData: inputData,
);
refreshes the product locally (that's where you would notify your provider)
Seems like I can't access the context
or any dart plugins, nor evensharedpref
when using workmanager
, so how exactly to notify or do use provide here is being a bit tricky to me, currently what I was thinking is not show a snackbar to the user that the theupload has been queued it will be uploaded soon
@AshAman999 I'm not familiar with workmanager or isolate, just familiar enough to have noticed that there are limitations ;) That said, I think @g123k developed isolate for the barcode scan: you may find interesting ideas in his code.
Having a look at the isolate docs, you may find the answers you're looking for:
All Dart code runs in an isolate, and code can access classes and values only from the same isolate. Different isolates can communicate by sending values through ports (see ReceivePort, SendPort).
I'm not sure isolate is the technical solution for neither cases (barcode scan and file upload). A video about async/isolate: https://www.youtube.com/watch?v=5AxWC49ZMzs.
Well, if it was my project I would try at least running async
upload methods without await
. Which probably wouldn't help alerting the main app when it's done. Just an idea: it's probable that with isolate or with async methods you can open the database, so you can write in the database when you're done, frequently check the database to see if something has successfully been uploaded, and react accordingly. Not a very subtile notification, but that would probably work.
Good luck!
Additional interesting video here, about:
What
I've retested New product addition with a video. It's really long, especially on 4G. https://photos.app.goo.gl/w6VcqSpvyeqqp8z48