Android Firebase File Storage - Part 2: Downloading Files

    In Part 1, you've learned about integrating Firebase in your Android Studio project and  upload files from your app to Firebase Storage then.  Of course, in this part 2, I will talk about the remaining feature: downloading file with two options: as a byte array or a temporary file.

    Firstly, go to Firebase Console page and select your project, in the File Storage entry, you'll see all uploaded files like this:
    Now, we will dig to the the solution that download these files to your Android app.

Download file as a byte array

    As noted at part 1, in order to access your Firebase Storage files, you'll need to first get a reference to the FirebaseStorage object, and then create a StorageReference to your project's URL and the file that you want to download. You can find your project's URL at the top of the Files section of Storage in the Firebase Console.
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReferenceFromUrl("gs://filestorage-d5afb.appspot.com").child("nougat.jpg");
    If you only need to download the file as a byte[] and don't need it as a file, which is the more likely case when loading an image into an ImageView, then you can retrieve the bytes in a similar style:
                final long ONE_MEGABYTE = 1024 * 1024;

                //download file as a byte array
                storageRef.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
                    @Override
                    public void onSuccess(byte[] bytes) {
                        Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                        imageView.setImageBitmap(bitmap);
                        showToast("Download successful!");
                    }
                });
    In my sample project, this is the output for this process:

Download as a temporary file

    Let create a File object and attempt to load the file you want by calling getFile() method on your StorageReference with the new File object passed as a parameter. Since this operation happens asynchronously, you can also add OnSuccessListener and OnFailureListener interface to your call in order to handle result:
                try {
                    showProgressDialog("Download File", "Downloading File...");
                    final File localFile = File.createTempFile("images", "jpg");
                    storageRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener() {
                        @Override
                        public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
                            Bitmap bitmap = BitmapFactory.decodeFile(localFile.getAbsolutePath());
                            imageView.setImageBitmap(bitmap);
                            dismissProgressDialog();
                            showToast("Download successful!");
                        }
                    }).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception exception) {
                            dismissProgressDialog();
                            showToast("Download Failed!");
                        }
                    });
                } catch (IOException e ) {
                    e.printStackTrace();
                    Log.e("Main", "IOE Exception");
                }
    In my case, this downloaded file is an image so I set it to the ImageView. Moreover, you can do other works with the downloaded file depend on your own aim. This is output of my code:

Getting a file's URL

    Sometimes, if you wouldn't like to download the file, you only need it's URL, you can use getDownloadUrl() method on your StorageReference, which will give you a Uri pointing to the file's location:
storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener() {
                    @Override
                    public void onSuccess(Uri uri) {
                        Log.i("Main", "File uri: " + uri.toString());
                    }
                });
    And this is the output on Log Cat:

Some advanced options with uploading/downloading process

    As any Android developer can attest, sometimes the Android activity lifecycle can cause unexpected issues. Fortunately, Firebase SDK has provided the way to keep all active download/upload tasks and you can restore them when your Activity recreated (by override onSaveInstanceState() and onRestoreInstanceState(). For the details, please read at handling Activity lifecycle change at File Storage official document, I won't talk about this on this simple tutorial.
    In particular about uploading process, there are some methods to control the UploadTask state: pause(), resume(), cancel(). In addition, you can use an OnPauseListener and OnProgressListener to keep track of upload progress and pause states. You can read more at the upload process document.

Conclusions

    Through 2 parts of Firebase File Storage tutorial, I hope that you've learned one more feature of Firebase back-end service and able to apply to your own work. You now understand the way to upload and download files, control data transfers,...when these tasks are occurring. With more tutorials about Firebase, please visit this link.
    References:

Share


Previous post
« Prev Post
Next post
Next Post »