Firebase Cloud Storage in Android App- Image Upload

 

Firebase cloud storage :

Firebase Cloud Storage provides a storage option for users who want to store media such as photos and videos kind of multimedia content.

When a user wants to integrate photo / video uploading features we can make use of cloud storage which is a cost effective and provides a google security features.

 

 

Not only in terms of authentication and security its much faster and easier in implementation of sdk into our code because we need not code any server side coding just make use of available resources through console.

In firebase cloud storage console we are providing public rule when you are creating realtime app make private access.

firebase cloud storage

 

Dependency’s :

We need to add android firebase cloud storage, firebase authentication, glide dependency’s

implementation 'com.google.firebase:firebase-storage-ktx:19.1.1'
implementation 'com.google.firebase:firebase-auth-ktx:19.3.1'

implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

 

 

Firebase cloud storage project structure :

This image depicts the usage of android firebase cloud storage project implementation.

firebase cloud storage project structure

 

activity_main.xml :

In this blog i want to upload image into firebase cloud storage and download back to device and set it into imageview using glide image library.

We can delete the image and set metadata to it by adding two buttons to the view.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".MainActivity">

    <ImageView
        android:id="@+id/img_view_upload"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_marginTop="28dp"
        android:src="@drawable/logo"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.854"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="92dp"
        android:text="image upload view "
        app:layout_constraintEnd_toStartOf="@+id/img_view_upload"
        app:layout_constraintHorizontal_bias="0.523"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <Button
        android:id="@+id/btn_upload_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="48dp"
        android:text="Upload"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.219"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/img_view_upload" />

    <Button
        android:id="@+id/btn_delete_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="48dp"
        android:text="Delete"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.795"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/img_view_upload" />


    <ImageView
        android:id="@+id/img_view_download"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_marginStart="40dp"
        android:layout_marginLeft="40dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_download_image"
        app:layout_constraintVertical_bias="0.332" />


    <Button
        android:id="@+id/btn_download_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="68dp"
        android:layout_marginLeft="68dp"
        android:layout_marginTop="20dp"
        android:text="Download"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_upload_image" />


    <Button
        android:id="@+id/btn_set_metadata"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="Set Metadata"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.495"
        app:layout_constraintStart_toEndOf="@+id/btn_download_image"
        app:layout_constraintTop_toBottomOf="@+id/btn_delete_image" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="160dp"
        android:text=" image download view"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.45"
        app:layout_constraintStart_toEndOf="@+id/img_view_download"
        app:layout_constraintTop_toBottomOf="@+id/btn_delete_image"
        app:layout_constraintVertical_bias="0.183" />


</androidx.constraintlayout.widget.ConstraintLayout>

 

MainActivity.java

Declare the objects for android firebase cloud storage reference.

lateinit var storageRef : StorageReference
lateinit var logoRef : StorageReference
lateinit var logoImagesRef : StorageReference

 

initialize them

val storage = FirebaseStorage.getInstance()
storageRef = storage.reference

 

assign a image to reference

logoRef = storageRef.child("logo.png")
logoImagesRef = storageRef.child("drawable/logo.png")

 

set onClickListener’s for buttons here we can also use view binding’s

btn_upload_image.setOnClickListener(this)
btn_delete_image.setOnClickListener(this)
btn_set_metadata.setOnClickListener(this)
btn_download_image.setOnClickListener(this)

 

uploadImage :

Convert the image to bitmap and compress it to make ready for upload and then upload the image to cloud storage.

private fun uploadImg() {

    logoRef.name == logoImagesRef.name // true
    logoRef.path == logoImagesRef.path // false

    img_view_upload.isDrawingCacheEnabled = true
    img_view_upload.buildDrawingCache()
    val bitmap = (img_view_upload.drawable as BitmapDrawable).bitmap
    val baos = ByteArrayOutputStream()
    bitmap.run {
        compress(Bitmap.CompressFormat.JPEG, 100, baos)
    }
    val data = baos.toByteArray()

    var uploadTask = logoRef.putBytes(data)
    uploadTask.addOnFailureListener {
        // Handle unsuccessful uploads
        Toast.makeText(this, "Fail", Toast.LENGTH_SHORT).show()
    }.addOnSuccessListener {
        Toast.makeText(this, "Success", Toast.LENGTH_SHORT).show()
    }

}

 

downloadImage :

Now we are downloading the image and set it using the glide to the imageview

private fun downloadImage() {

    storageRef.child("logo.png").downloadUrl.addOnSuccessListener { uri ->

        Glide.with(this).load(uri).into(img_view_download)

    }.addOnFailureListener {
        // Uh-oh, an error occurred!
    }
}

 

deleteImage :

We can delete the image using the image name and extension.

private fun deleteImage() {

    storageRef.child("logo.png").delete().addOnSuccessListener {
        // File deleted successfully
        Toast.makeText(this, "File Deleted", Toast.LENGTH_SHORT).show()

    }.addOnFailureListener {
        // Uh-oh, an error occurred!
    }
}

 

setMetadataToImage :

Here we are setting value, name, website as metdata fields to the image.

private fun setMetadata() {

    val metadata = storageMetadata {
        contentType = "image/png"
        setCustomMetadata("value", "logo")
        setCustomMetadata("name", "androidcoding")
        setCustomMetadata("website", "androidcoding.in")
    }

    storageRef.child("logo.png").updateMetadata(metadata).addOnSuccessListener {it->
        Toast.makeText(this, "Updated metadata" + it, Toast.LENGTH_SHORT).show()
    }.addOnFailureListener {
        // Uh-oh, an error occurred!
    }
}

 

Let’s see the screen below showing the image uploaded into firebase console

firebase cloud storage

 

Firebase cloud storage Full Code :

Providing the full source code for android firebase cloud storage implementation.

import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import com.google.firebase.storage.FirebaseStorage
import com.google.firebase.storage.StorageReference
import com.google.firebase.storage.ktx.storageMetadata
import kotlinx.android.synthetic.main.activity_main.*
import java.io.ByteArrayOutputStream

class MainActivity : AppCompatActivity() ,View.OnClickListener{

    lateinit var storageRef : StorageReference
    lateinit var logoRef : StorageReference
    lateinit var logoImagesRef : StorageReference

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val storage = FirebaseStorage.getInstance()

        storageRef = storage.reference

        logoRef = storageRef.child("logo.png")

        logoImagesRef = storageRef.child("drawable/logo.png")


        btn_upload_image.setOnClickListener(this)
        btn_delete_image.setOnClickListener(this)
        btn_set_metadata.setOnClickListener(this)
        btn_download_image.setOnClickListener(this)

    }

    override fun onClick(v: View?) {
        when(v!!.id){

            R.id.btn_upload_image -> {

               uploadImg()
            }

            R.id.btn_delete_image -> {

                deleteImage()
            }

            R.id.btn_download_image -> {

                downloadImage()

            }

            R.id.btn_set_metadata -> {

                setMetadata()
            }
        }
    }

    private fun setMetadata() {

        val metadata = storageMetadata {
            contentType = "image/png"
            setCustomMetadata("value", "logo")
            setCustomMetadata("name", "androidcoding")
            setCustomMetadata("website", "androidcoding.in")
        }

        storageRef.child("logo.png").updateMetadata(metadata).addOnSuccessListener {it->
            Toast.makeText(this, "Updated metadata" + it, Toast.LENGTH_SHORT).show()
        }.addOnFailureListener {
            // Uh-oh, an error occurred!
        }
    }

    private fun downloadImage() {

        storageRef.child("logo.png").downloadUrl.addOnSuccessListener { uri ->

            Glide.with(this).load(uri).into(img_view_download)

        }.addOnFailureListener {
            // Uh-oh, an error occurred!
        }
    }

    private fun deleteImage() {

        storageRef.child("logo.png").delete().addOnSuccessListener {
            // File deleted successfully
            Toast.makeText(this, "File Deleted", Toast.LENGTH_SHORT).show()

        }.addOnFailureListener {
            // Uh-oh, an error occurred!
        }
    }

    private fun uploadImg() {

        logoRef.name == logoImagesRef.name // true
        logoRef.path == logoImagesRef.path // false

        img_view_upload.isDrawingCacheEnabled = true
        img_view_upload.buildDrawingCache()
        val bitmap = (img_view_upload.drawable as BitmapDrawable).bitmap
        val baos = ByteArrayOutputStream()
        bitmap.run {
            compress(Bitmap.CompressFormat.JPEG, 100, baos)
        }
        val data = baos.toByteArray()



        var uploadTask = logoRef.putBytes(data)
        uploadTask.addOnFailureListener {
            // Handle unsuccessful uploads
            Toast.makeText(this, "Fail", Toast.LENGTH_SHORT).show()
        }.addOnSuccessListener {
            Toast.makeText(this, "Success", Toast.LENGTH_SHORT).show()
        }

    }
}

 

Firebase cloud storage output :

This screen depicts the usage of android firebase cloud storage.

firebase cloud storage

 

If any query’s in this tutorial on android firebase cloud storage let us know in comment section below.

For more interesting tutorials share and like this tutorial.

Show Buttons
Hide Buttons
Read previous post:
Android Multilevel Spinner – multilevel spinner

Android multilevel spinner is used to select a option from list available, a drop down list is populated when user...

Close