Android Firebase file storage
This tutorial will introduce you to the file storage and retrieval feature of Firebase. To learn more about Firebase’s real-time database, analytics, crash reporting and authentication, check out my other tutorials .
We’ll create a simple app with an ImageView and two upload and download buttons. User will choose an image from gallery and upload it to firebase. Or and image from firebase storage will be loaded into the imageView when user clicks download photo.
Authentication setup
Before you can begin using Firebase storage, you’ll need to either make sure your user is authenticated, or change the authentication requirement rules in the Firebase console to allow unauthenticated users to access and upload files. To do so, go into the Storage section of the console. Then, select the rules tab and change to the following:
Now you can work on your project without having to authenticate each time you run. Note that this is not ideal for a production environment. You only do this when you’re testing your work.
Uploading to firebase from an Android app
Let’s start by preparing the ui. We’ll add and imageview and two buttons for upload and download to activity_main.xml as follows:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="80px" tools:context="com.androidprojects.esprit.firebasefilestoragetutorial.MainActivity"> <Button android:id="@+id/btnDownload" android:layout_width="500px" android:layout_height="200px" android:text="Download photo" android:layout_alignParentTop="true"/> <Button android:id="@+id/btnUpload" android:layout_width="500px" android:layout_height="200px" android:text="Upload photo" android:layout_alignParentTop="true" android:layout_toRightOf="@id/btnDownload"/> <ImageView android:id="@+id/myImg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@android:drawable/ic_menu_gallery/> </RelativeLayout>
Implement the onActivityResult() method and add the following to the myImg.setOnClickListener() to launch the files chooser:
findViewById(R.id.myImg).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // file picker Intent i = new Intent(); i.setType("image/*"); i.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(i, "Select Picture"), 100); } });
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if(resultCode== Activity.RESULT_OK){ if(requestCode==100){ Uri selectedImageUri = data.getData(); if (null != selectedImageUri) { ((ImageView)findViewById(R.id.myImg)).setImageURI(selectedImageUri); } } } }
then under the btnUpload.setOnClickListener() add the following:
/** uploading **/ findViewById(R.id.btnUpload).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // store the image StorageReference _storageRef = storageRef.child("myuploadedfile.png"); (findViewById(R.id.myImg)).setDrawingCacheEnabled(true); (findViewById(R.id.myImg)).buildDrawingCache(); Bitmap bitmap = (findViewById(R.id.myImg)).getDrawingCache(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); byte[] data = baos.toByteArray(); UploadTask uploadTask = _storageRef.putBytes(data); uploadTask.addOnFailureListener(exception -> { Toast.makeText(MainActivity.this, "TASK FAILED", Toast.LENGTH_SHORT).show(); }).addOnSuccessListener(taskSnapshot -> { Toast.makeText(MainActivity.this, "TASK SUCCEEDED", Toast.LENGTH_SHORT).show(); Uri downloadUrl = taskSnapshot.getDownloadUrl(); String DOWNLOAD_URL = downloadUrl.getPath(); Log.v("DOWNLOAD URL", DOWNLOAD_URL); Toast.makeText(MainActivity.this, DOWNLOAD_URL, Toast.LENGTH_SHORT).show(); }); } });
Run your project and check the storage section on firebase console, you’ll find your image have been uploaded :
-
Uploading from an InputStream or File
Now that you know how to upload a byte array, the other two types of uploads should be fairly intuitive. Let’s say we have a text file named test.txt in our raw resources folder. We can read this into an InputStream and then upload it by using the putStream(InputStream) method of StorageReference.
Add a SecondActivity.java class and make it the launcher activity in your manifest file. This is the code for activity_second.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="80px"> <Button android:id="@+id/btnUploadNewFile" android:layout_width="500px" android:layout_height="200px" android:text="ChooseFile" android:layout_alignParentTop="true"/> <Button android:id="@+id/btnUploadToExsitingFile" android:layout_width="500px" android:layout_height="200px" android:text="Upload file" android:layout_alignParentTop="true" android:layout_toRightOf="@id/btnUploadNewFile"/> </RelativeLayout>
Then under the btnUploadNewFile.setOnClickListener you’ll add the following:
Not that you need to add your row resource directory with a test_upload.txt file.
findViewById(R.id.btnUploadNewFile).setOnClickListener(view -> { InputStream stream = getResources().openRawResource(R.raw.test_upload); UploadTask uploadTask = storageRef.child("test_upload.txt").putStream(stream); });
Uploading an existing file is just as easy: simply get a reference to the file and call putFile(uri) with a URI pointing to your file. For this example, we’ll just create an empty temp file in our code under the btnUploadToExistingFile:
findViewById(R.id.btnUploadToExistingFile).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { File file = File.createTempFile("test", "txt"); UploadTask uploadTask = storageRef.child("test.txt").putFile(Uri.fromFile(file)); } catch( IOException e ) { } } });
Downloading files to an Android app
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. To do so, we’ll be using our storageRef variable, with a reference to the ‘album2.png’ file we need to download.
To try to load the file we want, we’ll call getFile on our storageRef.child(“album2.png”) with the new File object passed as a parameter. Since this operation happens asynchronously, we can add an OnSuccessListener and onFailureListener to our call , to either set the downloaded image to the ImageView, or handle the exception in case of failure.
/** downloading **/ findViewById(R.id.btnDownload).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { final File localFile; try { localFile = File.createTempFile("album2", "png"); storageRef.child("album2.png").getFile(localFile).addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) { Bitmap bitmap = BitmapFactory.decodeFile(localFile.getAbsolutePath()); ((ImageView)findViewById(R.id.myImg)).setImageBitmap(bitmap); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { Log.d("FAILURE",exception.getMessage()); } }); } catch (IOException e) { e.printStackTrace(); } } });
Run your project and check you’re download succeeded:


• Downloading files as a Byte array
If you 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 way:
final long ONE_MEGABYTE = 1024 * 1024; storageRef.child("album2.png").getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() { @Override public void onSuccess(byte[] bytes) { Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); ((ImageView)findViewById(R.id.myImg)).setImageBitmap(bitmap); } });
That’s all coders ! You can download the source code for this tutorial here.
Recent Comments