How to publish image files using Firebase Storage in offline mode?

Asked

Viewed 50 times

1

Hello, I’m developing a code within Android Studio that allows data registration in a form with text fields and an image file offline (mobile with no internet connection). Works great with FirebaseDatabase.getInstance() but with the FirebaseStorage.getInstance(), that is, with the two together, (text and image) errors occur.

the idea is to save the data (text and its image attached) locally in the Smartphone (including consult) and when the same connect in some internet network the same synchronize the data in the server of Firebase.

I did tests using only texts and works very well, but if I take a photo and attach the same in the form, nothing happens.

Any suggestions? Has anyone faced a similar problem to this?

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //
        mFirebaseData = FirebaseDatabase.getInstance();
        mDatabaseReference = mFirebaseData.getReference("Data");
        mDatabaseReference.keepSynced(true);
        //storage
        mStorageReference = FirebaseStorage.getInstance().getReference();

2 answers

0

Here’s a practical example of what you asked:

In this example, let’s upload an image to the FirebaseStorage. For this, I suppose that the steps for image acquisition via camera or gallery is known in advance.

You can start background thread from a button:

     saveStoreData.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (isFormFieldsFilled()) {

                DocumentReference docRef = DatabaseRouter.getStoresCollectionRef().document();
                String key = docRef.getId();

                // Create a Constraints object that defines when the task should run
                Constraints constraints = new Constraints.Builder()
                        .setRequiredNetworkType(NetworkType.CONNECTED)
                        .build();

                // Passing data to the worker class
                Data.Builder builder = new Data.Builder();
                builder.putString("image_uri", profileImageUri.toString());
                builder.putString("image_pushkey", key);
                Data inputData = builder.build();

                // ...then create a OneTimeWorkRequest that uses those constraints
                OneTimeWorkRequest uploadWorkRequest = new OneTimeWorkRequest
                        .Builder(UploadImageToServerWorker.class)
                        .setConstraints(constraints)
                        .setInputData(inputData)
                        .build();

                // Execute and Manage the background service
                WorkManager workManager = WorkManager.getInstance(getActivity());
                workManager.enqueue(uploadWorkRequest);

            }

        }
    });

Now just create the Worker class: Uploadimagetoserverworker

public class UploadImageToServerWorker extends Worker {

    // https://www.raywenderlich.com/6040-workmanager-tutorial-for-android-getting-started

    private static final String TAG = "debinf UploadWorker";

    public UploadImageToServerWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        String imageUriInput = getInputData().getString("image_uri");
        String imagePushKey = getInputData().getString("image_pushkey");
        Log.i(TAG, "doWork: BACKGROUND WORK STARTED FOR KEY: "+imagePushKey);

        final Result[] result = {Result.retry()};
        CountDownLatch countDownLatch = new CountDownLatch(1);
        StorageReference storageRef = DatabaseRouter.getStoresStorageRef(imagePushKey).child(imagePushKey+".jpg");
        storageRef.putFile(Uri.parse(imageUriInput)).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
                if (task.isSuccessful()) {
                    Log.i(TAG, "onComplete: image uploaded successfuly!");
                    result[0] = Result.success();
                } else {
                    Log.i(TAG, "onComplete: image NOT uploaded - RETRYING");
                    result[0] = Result.retry();
                }
                countDownLatch.countDown();
            }
        });

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return result[0];
    }
}

Ready! I do not know if this is the most appropriate method, but it gives the service.

"Problems" that I found:

1) Sending the image is done without internet connection, but the internet connection is reestablished before of the connection timeout with FirebaseStorage: The method doWork() is executed 2 times.

2) Sending the image is done without internet connection and the internet connection is reestablished afterward of the connection timeout with FirebaseStorage: The mercy doWork() does not run as soon as the internet returns.

Well... I hope I helped and good luck!

-1


Save your images using local database and use the Workmanager library that works in the background to sync to firebase when internet is available.

  • Right, very grateful for the tip. Any examples of implementing this? link with examples or documentation maybe?

  • Yes my friend.... take a look at this video so you can enter the subject: https://www.youtube.com/watch?v=P3DO1MRN89M

  • Then you can search for more examples....

  • I will look yes, thanks for the tips.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.