ZOFTINO.COM android and web dev tutorials

Firebase Cloud Storage Upload, Download & Delete Files Android Example

In this post, I’ll explain how to create in android application a feature that allows users to upload local files to cloud and to list, download and delete cloud files with an example.

For this, I’ll use Firebase cloud storage which can be accessed using Firebase SDK for cloud storage. Since Firebase cloud storage stores files in Google cloud storage, files uploaded from android can be accessed from server using Google cloud platform.

Table of Contents

Firebase Cloud Storage Android Example

Our example app lets user enter file name in a text field. File can be any type of file on the device from public folders such as downloads, pictures, movies and music, etc. You can improve the way user inputs a file for uploading either by providing list of files for user to select or some other way.

Once file name is available, there is a check to make sure that the file exists on the device. If it doesn’t exist, message will be displayed to user. Next the file will be uploaded to cloud storage using Firebase cloud storage API.

Then file names will be stored in Firebase firestore database to track all the files uploaded and same data can be used to show a list files which are uploaded by the user. The list is displayed in RecyclerView with actions for each file to perform download and delete it from cloud.

Example Output

File upload screen

firebase cloud storage upload files android example

Uploaded files screen with options to download and delete.

firebase cloud storage files list, upload file, download file, android example

Project Set Up

First you need to create Firebase project. To do that, login to Firebase console, add your project to Firebase by clicking add project, then select the added project, click add-Firebase to android project and follow steps to generate google-services.json. Download the file and save it in your project in app folder.

Then to install Firebase SDK and setup your android project, add 'com.google.gms.google-services' plug-in to bottom of app level gradle build file and add gsm library 'com.google.gms:google-services:3.1.0' to classpath in project level gradle build file.

Then add firebase storage and firestore libraries to project by adding below entries to build.gradle file.

implementation 'com.google.firebase:firebase-storage:11.6.2'
implementation 'com.google.firebase:firebase-firestore:11.6.2'

Permissions

For this example, since we upload and download files to cloud, we need Internet permission. As we access public folders, we also need read and write external storage permissions as shown below.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/> 

Upload File

To upload files to Firebase cloud storage, first FirebaseStorage object is created by calling getInstance method on FirebaseStorage, then StorageReference of root node is obtained by calling getReference method on FirebaseStorage object, then StorageReference of the file that is going to be uploaded is created by calling child method on the root StorageReference object and passing file path and finally putFile method on the StorageReference object which represents the storage reference of the file being uploaded is called passing the file Uri.

You can listen to results by adding either OnSuccessListener or OnCompleteListener to StorageReference object. Once file has been uploaded to cloud storage, file information such as file name, create date and user will be added Firestore database.

 FirebaseStorage firebaseStorage = FirebaseStorage.getInstance();
StorageReference storageRef = firebaseStorage.getReference();
StorageReference uploadeRef = storageRef.child(toFilePath);

uploadeRef.putFile(fileUri).addOnFailureListener(new OnFailureListener(){
	public void onFailure(@NonNull Exception exception){
		Log.e(TAG,"Failed to upload file to cloud storage");
	}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>(){
	@Override
	public void onSuccess(UploadTask.TaskSnapshot taskSnapshot){
		Toast.makeText(getActivity(),
				"File has been uploaded to cloud storage",
				Toast.LENGTH_SHORT).show();
	}
}); 

Download File

Similarly, to download a file from cloud storage, you need to call getFile on the StorageReference object which represents the storage reference of the file being downloaded. To the getFile method, you need to pass local file path that the file being downloaded will be saved as.

 StorageReference storageRef = firebaseStorage.getReference();
StorageReference downloadRef = storageRef.child(userPath+fileName);
File fileNameOnDevice = new File(DOWNLOAD_DIR+"/"+fileName);
downloadRef.getFile(fileNameOnDevice).addOnSuccessListener …

Delete File

Similarly, to delete a file from cloud storage, you need to call delete method on StorageReference object.

 StorageReference storageRef = firebaseStorage.getReference();
StorageReference deleteRef = storageRef.child(userPath+fileName);
deleteRef.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
    @Override
    public void onComplete(@NonNull Task<Void> task) {
    }
}); 

View Files

To show list of files user uploaded to the cloud storage, data from Firestore database is retrieved for the user and displayed in recycler view. The example also provides a filter based on uploaded date. For each file displayed in Recycler view, download and delete options are provided.

Security

Since files uploaded to cloud storage needs to be protected from unauthorized access and only users who uploaded them should be able to view, download and delete, app needs to authenticate and authorize users.

To authenticate users, you can use Firebase email and password authentication and Firebase phone number authentication or other type of firebase authentication.

By default Firebase cloud storage allows only authenticated users to read from and write to it. To authorize a user to allow him to read only his files, first files needs to be saved under a node with node name as user id and then define a security rule to allow users to read files from child nodes of the node that matches to authenticated user id as shown below. You need to add this storage security rule in Firebase console.

 service firebase.storage {
  match /b/{bucket}/o {
    match /user/{userId}/{allPaths=**} {
      allow read, write: if request.auth.uid == userId;
    }
  }
} 

Since we are using Firestore to track uploaded files, we need to define security rules for Firestore also as shown below.

 service cloud.firestore {
  match /databases/{database}/documents {
    match /files/{userId} {
      allow read, write: if request.auth.uid == userId;
    }
  }
} 

Activity

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;

import zoftino.com.firestore.EmailPasswordAuthActivity;
import zoftino.com.firestore.MainActivity;
import zoftino.com.firestore.R;

public class FilesActivity extends AppCompatActivity {

    private FirebaseUser user;
    private static final String TAG = "FilesActivity";
    private FragmentManager fm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.files_activity_layout);

        user = FirebaseAuth.getInstance().getCurrentUser();
        if(user == null){
            //if user is not authenticated show authentication screen
            Intent i = new Intent();
            i.setClass(this, EmailPasswordAuthActivity.class);
            startActivity(i);
        }

        Toolbar tb = findViewById(R.id.toolbar);
        setSupportActionBar(tb);
        tb.setSubtitle("Upload Files");

        fm = getSupportFragmentManager();

        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {

                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                Manifest.permission.READ_EXTERNAL_STORAGE},
                        1);

        }
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.file_menu, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.upload_file_m:
                addFileFrgmt(user.getUid());
                return true;
            case R.id.view_file_m:
                viewFilesFrgmt(user.getUid());
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    public void addFileFrgmt(String userId){
        Bundle bundle = new Bundle();
        bundle.putString("userId", userId);

        FileUploadFragment uploadFragment = new FileUploadFragment();
        uploadFragment.setArguments(bundle);

        FragmentTransaction ft = fm.beginTransaction();

        ft.replace(R.id.files_frame, uploadFragment);
        ft.commit();
    }
    public void viewFilesFrgmt(String userId){
        Bundle bundle = new Bundle();
        bundle.putString("userId", userId);

        ViewFilesFragment viewFilesFragment = new ViewFilesFragment();
        viewFilesFragment.setArguments(bundle);

        FragmentTransaction ft = fm.beginTransaction();
        ft.replace(R.id.files_frame, viewFilesFragment);
        ft.commit();
    }
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 1: {

                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG, "external public folder access granted");
                } else {
                    Log.e(TAG, "external public folder access denied sending user to main screen");
                    Toast.makeText(this,
                            "Please grant permission to access public folders to use the feature",
                            Toast.LENGTH_SHORT).show();
                    toMainScreen();
                }
                return;
            }
        }
    }
    private void toMainScreen(){
        Intent i = new Intent();
        i.setClass(this, MainActivity.class);
        startActivity(i);
    }
}

Activity Layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="zoftino.com.firebase.storage.FilesActivity">
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary" />
    <FrameLayout
        android:id="@+id/files_frame"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="8dp"
        android:layout_marginStart="8dp"/>
</LinearLayout>

Upload Fragment

import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;

import java.io.File;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import zoftino.com.firestore.R;


public class FileUploadFragment extends Fragment {

    private static final String TAG = "FileUploadFragment";

    private FirebaseStorage firebaseStorage;
    private FirebaseFirestore firestoreDB;
    private EditText filePath;

    private String userId;
    private String userPath;

    private static final String[] PUBLIC_DIR = {Environment.getExternalStoragePublicDirectory
            (Environment.DIRECTORY_DOWNLOADS).getPath(),
            Environment.getExternalStoragePublicDirectory
                    (Environment.DIRECTORY_PICTURES).getPath(),
            Environment.getExternalStoragePublicDirectory
                    (Environment.DIRECTORY_MUSIC).getPath(),
            Environment.getExternalStoragePublicDirectory
                    (Environment.DIRECTORY_MOVIES).getPath()};

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        userId = getArguments().getString("userId");
        userPath = "user/" + userId + "/";

        View view = inflater.inflate(R.layout.file_upload_layout,
                container, false);

        Button button = (Button) view.findViewById(R.id.upload_b);
        filePath = view.findViewById(R.id.file_name);

        firebaseStorage = FirebaseStorage.getInstance();
        firestoreDB = FirebaseFirestore.getInstance();

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                uploadFile(filePath.getText().toString());
            }
        });

        return view;
    }


    public void uploadFile(final String fileNme) {
        String filePath = getFilePath(fileNme);
        if(filePath == null){
            Log.e(TAG, "File doesn't exist");
            Toast.makeText(getActivity(),
                    "File not found, please enter correct file name",
                    Toast.LENGTH_SHORT).show();
            return;
        }
        File file = new File(filePath);
        Uri fileUri = Uri.fromFile(file);

        final String toFilePath = userPath + fileUri.getLastPathSegment();

        StorageReference storageRef = firebaseStorage.getReference();
        StorageReference uploadeRef = storageRef.child(toFilePath);

        uploadeRef.putFile(fileUri).addOnFailureListener(new OnFailureListener() {
            public void onFailure(@NonNull Exception exception) {
                Log.e(TAG, "Failed to upload file to cloud storage: " + exception.toString());
                Toast.makeText(getActivity(),
                        "Upload failed",
                        Toast.LENGTH_SHORT).show();
            }
        }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                //add file name to firestore database
                addFileNameToDB(fileNme);
                Uri downloadUrl = taskSnapshot.getDownloadUrl();
                Toast.makeText(getActivity(),
                        "File has been uploaded to cloud storage",
                        Toast.LENGTH_SHORT).show();
            }
        });
    }

    private String getFilePath(String fName) {
        File file;
        String tFile;
        for (String dir : PUBLIC_DIR) {
            tFile = dir +"/"+fName;
            Log.e(TAG, tFile);
            file = new File(tFile);
            if (file.exists()) {
                return tFile;
            }
        }
        return null;
    }

    private void addFileNameToDB(final String fileNAME) {
        String docKey = userId+fileNAME;
        Map<String, String> mp = new HashMap<String, String>();
        mp.put("storagePath", fileNAME);
        mp.put("date", getTodaysDate());
        mp.put("userId", userId);

        firestoreDB.collection("files").document(docKey)
                .set(mp)
                .addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        if (task.isSuccessful()) {
                            Log.d(TAG, "file name has been added to firestore db ");
                        } else {
                            Log.e(TAG, "failed to add file name to db " + fileNAME);
                        }
                        restUi();
                    }
                });
    }

    private String getTodaysDate() {
        Date currentDate = Calendar.getInstance().getTime();
        java.text.SimpleDateFormat simpleDateFormat = new java.text.SimpleDateFormat("MM/dd/YYYY");
        return simpleDateFormat.format(currentDate);
    }

    private void restUi() {
        filePath.setText("");
    }
}

Upload Fragment Layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="zoftino.com.firebase.storage.FilesActivity">
    <TextView
        android:id="@+id/heading_upload"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Headline"
        android:text="Upload Files"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"  />

    <android.support.design.widget.TextInputLayout
        android:id="@+id/file_name_lv"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/heading_upload">
        <android.support.design.widget.TextInputEditText
            android:id="@+id/file_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Enter file name from downloads, pictures, music or movies folders" />
    </android.support.design.widget.TextInputLayout>
    <Button
        android:id="@+id/upload_b"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        style="@style/Widget.AppCompat.Button.Colored"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/file_name_lv"
        android:text="Upload File"/>
</android.support.constraint.ConstraintLayout>

List Fragment

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QuerySnapshot;

import java.util.ArrayList;
import java.util.List;

import zoftino.com.firestore.R;

public class ViewFilesFragment extends Fragment {

    private static final String TAG = "ViewFilesFragment";

    private FirebaseFirestore firestoreDB;
    private String userId;

    private RecyclerView filesRecyclerView;
    private EditText createDate;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        userId = getArguments().getString("userId");

        View view = inflater.inflate(R.layout.file_list_layout,
                container, false);

        firestoreDB = FirebaseFirestore.getInstance();

        filesRecyclerView = (RecyclerView) view.findViewById(R.id.files_lst);
        createDate =  view.findViewById(R.id.create_date);

        Button searchButton = (Button) view.findViewById(R.id.search_files_b);
        searchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getFielNames();
            }
        });


        LinearLayoutManager recyclerLayoutManager =
                new LinearLayoutManager(getActivity().getApplicationContext());
        filesRecyclerView.setLayoutManager(recyclerLayoutManager);

        DividerItemDecoration dividerItemDecoration =
                new DividerItemDecoration(filesRecyclerView.getContext(),
                        recyclerLayoutManager.getOrientation());
        filesRecyclerView.addItemDecoration(dividerItemDecoration);

        return view;
    }
    private void getFielNames(){
        getFileNamesFromFirestoreDb(createDate.getText().toString());
    }
    private void getFileNamesFromFirestoreDb(String createDate) {
        firestoreDB.collection("files")
                .whereEqualTo("date", createDate)
                .whereEqualTo("userId", userId)
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if (task.isSuccessful()) {
                            List<String> fileList = new ArrayList<String>();
                            Log.d(TAG, "DOCS SIZE "+task.getResult().size());
                            for(DocumentSnapshot doc : task.getResult()){
                                fileList.add(doc.getString("storagePath"));
                            }
                            FilesRecyclerViewAdapter recyclerViewAdapter = new
                                    FilesRecyclerViewAdapter(fileList,
                                    getActivity(), userId);
                            filesRecyclerView.setAdapter(recyclerViewAdapter);

                        } else {
                            Log.d(TAG, "Error getting documents: ", task.getException());
                        }
                    }
                });
    }
}

List Fragment Layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="zoftino.com.firebase.storage.FilesActivity">
    <android.support.design.widget.TextInputLayout
        android:id="@+id/create_date_lv"
        android:layout_marginTop="4dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">
        <EditText
            android:id="@+id/create_date"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Create Date (MM/DD/YYYY)"/>
    </android.support.design.widget.TextInputLayout>
    <Button
        android:id="@+id/search_files_b"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        style="@style/Widget.AppCompat.Button.Colored"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/create_date_lv"
        android:text="Show Files"/>
    <android.support.v7.widget.RecyclerView
        android:id="@+id/files_lst"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/search_files_b"/>
</android.support.constraint.ConstraintLayout>

RecyclerView Adapter

import android.content.Context;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.storage.FileDownloadTask;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;

import java.io.File;
import java.util.List;

import zoftino.com.firestore.R;

public class FilesRecyclerViewAdapter extends
        RecyclerView.Adapter<FilesRecyclerViewAdapter.ViewHolder> {

    private List<String> fileList;
    private Context context;
    private FirebaseStorage firebaseStorage;
    private FirebaseFirestore firestoreDB;
    private String userId;
    private String userPath;

    private String DOWNLOAD_DIR = Environment.getExternalStoragePublicDirectory
            (Environment.DIRECTORY_DOWNLOADS).getPath();

    public FilesRecyclerViewAdapter(List<String> list, Context ctx, String uid) {
        fileList = list;
        context = ctx;
        userId = uid;
        userPath =  "user/" + uid + "/";
    }
    @Override
    public int getItemCount() {
        return fileList.size();
    }

    @Override
    public FilesRecyclerViewAdapter.ViewHolder
    onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.file_item_layout, parent, false);

        firebaseStorage = FirebaseStorage.getInstance();
        firestoreDB = FirebaseFirestore.getInstance();

        FilesRecyclerViewAdapter.ViewHolder viewHolder =
                new FilesRecyclerViewAdapter.ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(FilesRecyclerViewAdapter.ViewHolder holder, int position) {
        final int itemPos = position;
        final String fileName = fileList.get(position);
        holder.name.setText(fileName);

        holder.download.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                downloadFile(fileName);
            }
        });

        holder.delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                deleteFile(fileName, itemPos);
            }
        });
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public TextView name;
        public Button download;
        public Button delete;

        public ViewHolder(View view) {
            super(view);
            name = (TextView) view.findViewById(R.id.file_name_i);
            download = view.findViewById(R.id.download_file_b);
            delete = view.findViewById(R.id.delete_file_b);
        }
    }
    private void downloadFile(String fileName){
        StorageReference storageRef = firebaseStorage.getReference();
        StorageReference downloadRef = storageRef.child(userPath+fileName);
        File fileNameOnDevice = new File(DOWNLOAD_DIR+"/"+fileName);

        downloadRef.getFile(fileNameOnDevice).addOnSuccessListener(
                new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
                Log.d("File RecylerView", "downloaded the file");
                Toast.makeText(context,
                        "Downloaded the file",
                        Toast.LENGTH_SHORT).show();
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception exception) {
                Log.e("File RecylerView", "Failed to download the file");
                Toast.makeText(context,
                        "Couldn't be downloaded",
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
    private void deleteFile(final String fileName, final int iPos){
        StorageReference storageRef = firebaseStorage.getReference();
        StorageReference deleteRef = storageRef.child(userPath+fileName);
        deleteRef.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                if(task.isSuccessful()){
                    Log.d("File RecylerView", "delete the file");
                    Toast.makeText(context,
                            "File has been deleted",
                            Toast.LENGTH_SHORT).show();
                    fileList.remove(iPos);
                    notifyItemRemoved(iPos);
                    notifyItemRangeChanged(iPos, fileList.size());

                    deleteFileNameFromDB(fileName);

                }else{
                    Log.e("File RecylerView", "Failed to delete the file");
                    Toast.makeText(context,
                            "File Couldn't be deleted",
                            Toast.LENGTH_SHORT).show();
                }

            }
        });
    }
    private void deleteFileNameFromDB(String fileName){
       firestoreDB.collection("files").document(userId+fileName).delete()
                .addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        Log.e("File RecylerView", "File name deleted from db");
                    }
                });
    }
}

RecyclerView Item Layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    tools:context="zoftino.com.firebase.storage.FilesActivity">
    <TextView
        android:id="@+id/file_name_i"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/download_file_b"
        style="@style/Widget.AppCompat.Button.Colored"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minHeight="0dp"
        android:minWidth="0dp"
        android:text="Download"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/delete_file_b"
        app:layout_constraintTop_toBottomOf="@+id/file_name_i" />
    <Button
        android:id="@+id/delete_file_b"
        style="@style/Widget.AppCompat.Button.Colored"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minHeight="0dp"
        android:minWidth="0dp"
        android:text="Delete"
        app:layout_constraintLeft_toRightOf="@+id/download_file_b"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/file_name_i" />
</android.support.constraint.ConstraintLayout>