Open In App

Android: How to Upload an image on Firebase storage?

Last Updated : 03 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Firebase is a mobile and web application development platform. It provides services that a web application or mobile application might require. Firebase provides secure file uploads and downloads for Firebase application. This article explains how to build an Android application with the ability to select the image from the mobile gallery and upload images to Firebase Storage.

Note: Firebase Storage now requires a billing plane to use Firebase Storage.

Step by Step Implementation

Step 1: Create a new project

Create a new project on android studio or open an existing project in which you want and add the firebase to that android application.

Step 2: Add the firebase storage dependency

Navigate to Gradle Scripts > build.gradle.kts (Module:app) and add the following dependencies

dependencies {
...
implementation("com.google.firebase:firebase-storage-ktx:21.0.1")
}


Step 3. Setting up the activity_main.xml layout file

Navigate to app > res > layout > activity_main.xml and add the following code

activity_main.xml:

XML
<?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"
    android:background="@color/white">

    <!--Image View for showing image chosen from gallery-->
    <ImageView
        android:id="@+id/imgView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_margin="32dp"
        app:layout_constraintBottom_toTopOf="@+id/btnChoose"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <!--Button for choosing image from gallery-->
    <Button
        android:id="@+id/btnChoose"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="32dp"
        android:text="Choose"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/btnUpload"
        app:layout_constraintStart_toStartOf="parent" />

    <!--Button for uploading image-->
    <Button
        android:id="@+id/btnUpload"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Upload"
        app:layout_constraintBottom_toBottomOf="@+id/btnChoose"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/btnChoose"
        app:layout_constraintTop_toTopOf="@+id/btnChoose" />

</androidx.constraintlayout.widget.ConstraintLayout>


Step 4: Working with MainActivity file

Navigate to app > java > {package-name} > MainActivity.kt/.java and add the following code.

Set OnClickListeners on the buttons to handle user interaction. When the Select button is clicked, a image selection bottom sheet is displayed using ActivityResultLauncher with ActivityResultContracts.GetContent. This launches a system image picker letting the user to choose an image from their device’s gallery. Once the image is selected, its URI is returned, which is then displayed in the ImageView below the buttons.

When the Upload button is clicked, the uploadImage() method is called. Inside this method, a Firebase Storage reference is initialized and a unique file path is created using a UUID. If an image is selected, it is uploaded to Firebase using the putFile() function. A progress dialog shows the upload progress.

MainActivity.java
package org.geeksforgeeks.demo;

import android.app.ProgressDialog;
import android.graphics.*;
import android.net.Uri;
import android.os.Bundle;
import android.widget.*;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.google.firebase.ktx.Firebase;
import com.google.firebase.storage.*;

import java.io.InputStream;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    // Declare UI components
    private Button btnSelect;
    private Button btnUpload;
    private ImageView imageView;

    // Store the URI of the selected image
    private Uri filePath;

    // Firebase Storage instance
    private FirebaseStorage storage;

    // Reference to the Firebase Storage root directory
    private StorageReference storageReference;

    // Launcher to handle image picking from gallery
    private ActivityResultLauncher<String> imagePickerLauncher;

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

        // Bind UI elements to layout views
        btnSelect = findViewById(R.id.btnChoose);
        btnUpload = findViewById(R.id.btnUpload);
        imageView = findViewById(R.id.imgView);

        // Initialize Firebase Storage
        storage = StorageKt.getStorage(Firebase.INSTANCE);
        storageReference = storage.getReference();

        // Initialize image picker with activity result contract
        imagePickerLauncher = registerForActivityResult(
                new ActivityResultContracts.GetContent(),
                uri -> {
                    // Handle the result from the image picker
                    if (uri != null) {
                        filePath = uri;
                        try {
                            // Open input stream from the selected image URI
                            InputStream inputStream = getContentResolver().openInputStream(uri);

                            // Decode input stream into a Bitmap and display in ImageView
                            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                            imageView.setImageBitmap(bitmap);
                        } catch (Exception e) {
                            // Handle any exceptions during image decoding
                            e.printStackTrace();
                            Toast.makeText(MainActivity.this, "Failed to load image", Toast.LENGTH_SHORT).show();
                        }
                    }
                });

        // Set click listener to launch image picker
        btnSelect.setOnClickListener(v -> imagePickerLauncher.launch("image/*"));

        // Set click listener to upload the selected image
        btnUpload.setOnClickListener(v -> uploadImage());
    }

    // Function to upload selected image to Firebase Storage
    private void uploadImage() {
        // Check if an image has been selected
        if (filePath != null) {
            // Create and show a progress dialog during upload
            ProgressDialog progressDialog = new ProgressDialog(this);
            progressDialog.setTitle("Uploading...");
            progressDialog.show();

            // Create a unique path under 'images/' using UUID
            StorageReference ref = storageReference.child("images/" + UUID.randomUUID().toString());

            // Upload the file to Firebase Storage
            ref.putFile(filePath)
                .addOnSuccessListener(taskSnapshot -> {
                    // Dismiss the dialog and show success message
                    progressDialog.dismiss();
                    Toast.makeText(MainActivity.this, "Image Uploaded!!", Toast.LENGTH_SHORT).show();
                })
                .addOnFailureListener(e -> {
                    // Dismiss the dialog and show failure message
                    progressDialog.dismiss();
                    Toast.makeText(MainActivity.this, "Upload Failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                })
                .addOnProgressListener(taskSnapshot -> {
                    // Calculate and update progress percentage in the dialog
                    double progress = (100.0 * taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount());
                    progressDialog.setMessage("Uploaded " + (int) progress + "%");
                });
        } else {
            // Show message if no image is selected
            Toast.makeText(this, "No image selected!", Toast.LENGTH_SHORT).show();
        }
    }
}
MainActivity.kt
package org.geeksforgeeks.demo

import android.app.ProgressDialog
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.widget.*
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.ktx.Firebase
import com.google.firebase.storage.FirebaseStorage
import com.google.firebase.storage.ktx.storage
import java.io.InputStream
import java.util.UUID

class MainActivity : AppCompatActivity() {

    // Declare UI components
    private lateinit var btnSelect: Button
    private lateinit var btnUpload: Button
    private lateinit var imageView: ImageView

    // Store the URI of the selected image
    private var filePath: Uri? = null

    // Firebase Storage instance
    private lateinit var storage: FirebaseStorage

    // Reference to the Firebase Storage root directory
    private val storageReference by lazy { storage.reference }

    // Launcher to handle image picking from gallery
    private lateinit var imagePickerLauncher: ActivityResultLauncher<String>

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

        // Bind UI elements to layout views
        btnSelect = findViewById(R.id.btnChoose)
        btnUpload = findViewById(R.id.btnUpload)
        imageView = findViewById(R.id.imgView)

        // Initialize Firebase Storage
        storage = Firebase.storage

        // Initialize image picker with activity result contract
        imagePickerLauncher = registerForActivityResult(
            ActivityResultContracts.GetContent()
        ) { uri: Uri? ->
            // Handle the result from the image picker
            if (uri != null) {
                filePath = uri
                try {
                    // Open input stream from the selected image URI
                    val inputStream: InputStream? = contentResolver.openInputStream(uri)

                    // Decode input stream into a Bitmap and display in ImageView
                    val bitmap = BitmapFactory.decodeStream(inputStream)
                    imageView.setImageBitmap(bitmap)
                } catch (e: Exception) {
                    // Handle any exceptions during image decoding
                    e.printStackTrace()
                    Toast.makeText(this, "Failed to load image", Toast.LENGTH_SHORT).show()
                }
            }
        }

        // Set click listener to launch image picker
        btnSelect.setOnClickListener {
            imagePickerLauncher.launch("image/*")
        }

        // Set click listener to upload the selected image
        btnUpload.setOnClickListener {
            uploadImage()
        }
    }

    // Function to upload selected image to Firebase Storage
    private fun uploadImage() {
        // Check if an image has been selected
        if (filePath != null) {
            // Create and show a progress dialog during upload
            val progressDialog = ProgressDialog(this)
            progressDialog.setTitle("Uploading...")
            progressDialog.show()

            // Create a unique path under 'images/' using UUID
            val ref = storageReference.child("images/${UUID.randomUUID()}")

            // Upload the file to Firebase Storage
            ref.putFile(filePath!!)
                .addOnSuccessListener {
                    // Dismiss the dialog and show success message
                    progressDialog.dismiss()
                    Toast.makeText(this, "Image Uploaded!!", Toast.LENGTH_SHORT).show()
                }
                .addOnFailureListener { e ->
                    // Dismiss the dialog and show failure message
                    progressDialog.dismiss()
                    Toast.makeText(this, "Upload Failed: ${e.message}", Toast.LENGTH_SHORT).show()
                }
                .addOnProgressListener { taskSnapshot ->
                    // Calculate and update progress percentage in the dialog
                    val progress = (100.0 * taskSnapshot.bytesTransferred / taskSnapshot.totalByteCount)
                    progressDialog.setMessage("Uploaded ${progress.toInt()}%")
                }
        } else {
            // Show message if no image is selected
            Toast.makeText(this, "No image selected!", Toast.LENGTH_SHORT).show()
        }
    }
}


Output:

In App:


In Firebase console:




Next Article

Similar Reads