Android: How to Upload an image on Firebase storage? (original) (raw)
Last Updated : 12 Jul, 2025
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 `
<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:
