0

I use Android WorkManager to download file from Firebase Storage.
The code is as the following

    @NonNull
    @Override
    public Result doWork() {
        dowloadFile-1
        dowloadFile-2
        dowloadFile-3
        dowloadFile-4
        return Result.success();
    }
    // Create and start an unique work.    
    // It mean there is only one work running at the time   
    public static void start(Context context) {
        Constraints constraints = new Constraints.Builder()
                // The Worker needs Network connectivity
                .setRequiredNetworkType(NetworkType.CONNECTED)
                .build();
        int backoffDelay = context.getResources().getInteger(R.integer.sync_retry_backoff_delay);
        OneTimeWorkRequest worker = new OneTimeWorkRequest.Builder(FirebaseSyncService.class)
                .setConstraints(constraints)
                .setBackoffCriteria(BackoffPolicy.LINEAR, backoffDelay, TimeUnit.MINUTES)
                .build();
        WorkManager
                .getInstance(context)
                .enqueueUniqueWork(SYNC_WORK_ID, ExistingWorkPolicy.KEEP, worker);
    }
I use getWorkInfosForUniqueWorkLiveData()  to check state of unique work

And the scenario are as the following

  • Step-1. Connect internet then start work
  • Step-2. The program completed download file-1 and file-2 The work state now is RUNNING
  • Step-3. Disconnect internet
    Work will be stopped and WorkManager will retry by adding new Work to queue
    The work state now is ENQUEUED
  • Step-4. Re-connect internet

Expected:
After reconnecting internet, I expect the WorkManager will perform new work from beginning and the state is RUNING again.
I want to download file-1 and file-2 again.

Actual
WorkManager continue previous work and resume from downloading file-3. But the state is ENQUEUED.
Even if I change ExistingWorkPolicy.KEEP -> ExistingWorkPolicy.REPLACE, the behavior is the same.

Thank you for all supports

Vu Thai Duy
  • 169
  • 2
  • 12
  • Hi, as per your expected output, i think you must use Periodic Work Request, instead of OneTimeWorkRequest. – Dev007 Nov 19 '22 at 18:28
  • @Dev007 I only expect the work run one time only but retry from beginning if error occur or constrains not meet – Vu Thai Duy Nov 20 '22 at 14:25

1 Answers1

1

check these in your worker() Java file.

  • For doing network call you maybe using try catch, if not you have to use and then check in catch block you have to add return Result.Failure. Otherwise, even if you disconnect your internet it will continuous working(doWork() function),even work state is ENQUEUED and you will see exception in log.(Not sure reason, seems to be bug...)

I'm not faced these issue, when i use with Kotlin CoroutineWorker. its happening only if i use Worker

Note : I'll not suggest this type of coding, use Kotlin CoroutineWorker and forLoop for multiple series of file downloads. here i'm showing only for Demo purpose.

    @NonNull
    @Override
    public Result doWork() {

        try {
            dowloadFile-1
        }catch (Exception e){
            return Result.Failure; // this is important.Otherwise worker not finish,even work state is ENQUEUED
        }

        try {
            dowloadFile-2
        }catch (Exception e){
            return Result.Failure;
        }

        try {
            dowloadFile-3
        }catch (Exception e){
            return Result.Failure;
        }

        try {
            dowloadFile-4
        }catch (Exception e){
            return Result.Failure;
        }

        //all success
        return Result.success();
    }

Quick Tip, In your case - Its better to use ExistingWorkPolicy.REPLACE, and Network call in background thread(use CoroutineWorker())

Dev007
  • 222
  • 2
  • 9
  • I use try/catch for all work, not for each download. And there is no exception occur. I guess the work just pending and wait for network connected. I see the following log: ExponenentialBackoff: network unavailable, sleeping. In addition, downloading file is sync process. I use Tasks.await(item.getFile(localFile)); – Vu Thai Duy Nov 21 '22 at 15:12
  • I found this ticket https://stackoverflow.com/questions/46156808/firebase-storage-download-file-does-not-fail-when-network-unavilable It said that the download will not trigger exception if network is disconnected – Vu Thai Duy Nov 21 '22 at 15:33
  • I think you can use addOnFailureListener something, instead of try catch. Did you try adding Result.FAILURE in onResultFailure listener?? – Dev007 Nov 21 '22 at 17:48
  • even if you use onResultFailure listener, the failure will not trigger when internet is disconnect. In addition, I want to download file sequentially. That why i use Tasks.await – Vu Thai Duy Nov 22 '22 at 15:11
  • 1
    then, can you try with this - https://firebase.google.com/docs/database/android/offline-capabilities#section-connection-state . From here, if connected true internet available. if false you have to return Result.Failure() – Dev007 Nov 22 '22 at 16:08